Просмотр исходного кода

Merge pull request #38 from user6606/CoE

在etherkit_ethercat_coe中新增CyberGear示例
Yuqiang Wang 10 месяцев назад
Родитель
Сommit
960f6b4117
51 измененных файлов с 5875 добавлено и 69 удалено
  1. 6 0
      libraries/HAL_Drivers/drv_canfd.c
  2. 3 0
      projects/etherkit_basic_key_irq/board/Kconfig
  3. 3 0
      projects/etherkit_basic_rtc/board/Kconfig
  4. 3 0
      projects/etherkit_blink_led/board/Kconfig
  5. 3 0
      projects/etherkit_component_flash_fs/board/Kconfig
  6. 3 0
      projects/etherkit_component_mqtt/board/Kconfig
  7. 3 0
      projects/etherkit_component_netutils/board/Kconfig
  8. 3 0
      projects/etherkit_driver_adc/board/Kconfig
  9. 3 0
      projects/etherkit_driver_canfd/board/Kconfig
  10. 3 0
      projects/etherkit_driver_gpt/board/Kconfig
  11. 3 0
      projects/etherkit_driver_hyperram/board/Kconfig
  12. 3 0
      projects/etherkit_driver_i2c/board/Kconfig
  13. 3 0
      projects/etherkit_driver_rs485/board/Kconfig
  14. 3 0
      projects/etherkit_driver_spi/board/Kconfig
  15. 3 0
      projects/etherkit_driver_wdt/board/Kconfig
  16. 1 1
      projects/etherkit_ethercat_coe/.settings/standalone.prefs
  17. 11 0
      projects/etherkit_ethercat_coe/board/Kconfig
  18. 16 0
      projects/etherkit_ethercat_coe/board/ports/Cybergear/SConscript
  19. 613 0
      projects/etherkit_ethercat_coe/board/ports/Cybergear/cybergear.c
  20. 144 0
      projects/etherkit_ethercat_coe/board/ports/Cybergear/cybergear.h
  21. 290 0
      projects/etherkit_ethercat_coe/board/ports/Cybergear/cybergearapp.c
  22. 59 2
      projects/etherkit_ethercat_coe/board/ports/ethercat/beckhoff/Src/cia402appl.c
  23. 5 1
      projects/etherkit_ethercat_coe/board/ports/ethercat/beckhoff/Src/ecatappl.c
  24. 54 1
      projects/etherkit_ethercat_coe/board/ports/ethercat/ethercat_coe_app.c
  25. 154 42
      projects/etherkit_ethercat_coe/board/ports/ethercat/renesas/samplecia402.c
  26. 3 1
      projects/etherkit_ethercat_coe/board/ports/ethercat/renesas/samplecia402.h
  27. 8 1
      projects/etherkit_ethercat_coe/buildinfo.ipcf
  28. 207 13
      projects/etherkit_ethercat_coe/configuration.xml
  29. 38 0
      projects/etherkit_ethercat_coe/memory_regions.icf
  30. 260 0
      projects/etherkit_ethercat_coe/rzn/fsp/inc/api/r_can_api.h
  31. 368 0
      projects/etherkit_ethercat_coe/rzn/fsp/inc/instances/r_canfd.h
  32. 431 0
      projects/etherkit_ethercat_coe/rzn/fsp/inc/instances/r_gpt.h
  33. 1089 0
      projects/etherkit_ethercat_coe/rzn/fsp/src/r_canfd/r_canfd.c
  34. 1601 0
      projects/etherkit_ethercat_coe/rzn/fsp/src/r_gpt/r_gpt.c
  35. 81 0
      projects/etherkit_ethercat_coe/rzn_cfg/fsp_cfg/r_canfd_cfg.h
  36. 16 0
      projects/etherkit_ethercat_coe/rzn_cfg/fsp_cfg/r_gpt_cfg.h
  37. 268 0
      projects/etherkit_ethercat_coe/rzn_gen/hal_data.c
  38. 40 0
      projects/etherkit_ethercat_coe/rzn_gen/hal_data.h
  39. 14 6
      projects/etherkit_ethercat_coe/rzn_gen/pin_data.c
  40. 7 0
      projects/etherkit_ethercat_coe/rzn_gen/vector_data.c
  41. 19 1
      projects/etherkit_ethercat_coe/rzn_gen/vector_data.h
  42. 3 0
      projects/etherkit_ethercat_eoe/board/Kconfig
  43. 3 0
      projects/etherkit_ethernet/board/Kconfig
  44. 3 0
      projects/etherkit_ethernetip_opener/board/Kconfig
  45. 3 0
      projects/etherkit_factory/board/Kconfig
  46. 3 0
      projects/etherkit_modbus_tcpip/board/Kconfig
  47. 3 0
      projects/etherkit_modbus_uart/board/Kconfig
  48. 3 0
      projects/etherkit_profinet_pnet/board/Kconfig
  49. 3 0
      projects/etherkit_usb_pcdc/board/Kconfig
  50. 3 0
      projects/etherkit_usb_pmsc/board/Kconfig
  51. 3 0
      projects/template_project/board/Kconfig

+ 6 - 0
libraries/HAL_Drivers/drv_canfd.c

@@ -218,7 +218,13 @@ rt_ssize_t ra_can_sendmsg(struct rt_can_device *can_dev, const void *buf, rt_uin
     g_can_tx_frame.id_mode = (can_id_mode_t)msg_rt->ide;
     g_can_tx_frame.type = (can_frame_type_t)msg_rt->rtr;
     g_can_tx_frame.data_length_code = msg_rt->len;
+#if defined(BSP_USING_CANFD) && defined(BSP_USING_CAN_RZ)
+    g_can_tx_frame.options = 0;
+#elif defined(BSP_USING_CANFD)
     g_can_tx_frame.options = CANFD_FRAME_OPTION_FD | CANFD_FRAME_OPTION_BRS;
+#else
+    g_can_tx_frame.options = 0;
+#endif
     memcpy(g_can_tx_frame.data, msg_rt->data, 8);
     can = rt_container_of(can_dev, struct ra_can, can_dev);
     RT_ASSERT(boxno < can->config->num_of_mailboxs);

+ 3 - 0
projects/etherkit_basic_key_irq/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_basic_rtc/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_blink_led/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_component_flash_fs/board/Kconfig

@@ -105,6 +105,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_component_mqtt/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_component_netutils/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_adc/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_canfd/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_gpt/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_hyperram/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_i2c/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_rs485/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_spi/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_driver_wdt/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
projects/etherkit_ethercat_coe/.settings/standalone.prefs


+ 11 - 0
projects/etherkit_ethercat_coe/board/Kconfig

@@ -72,6 +72,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+                config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n
@@ -194,5 +197,13 @@ menu "Hardware Drivers Config"
                     hex "(HEX)RESET pin index"
                     default 0x1706
             endif
+        
+        config BSP_USING_CYBERGEAR_MOTOR
+        	bool "Enable CyberGear Motor"
+        	default n
+        	select BSP_USING_CANFD
+        	select BSP_USING_CANFD0
+        	select BSP_USING_CANFD1
+        	select BSP_USING_CAN_RZ
     endmenu
 endmenu

+ 16 - 0
projects/etherkit_ethercat_coe/board/ports/Cybergear/SConscript

@@ -0,0 +1,16 @@
+import os
+from building import *
+
+objs = []
+src = Glob('*.c')
+cwd  = GetCurrentDir()
+CPPPATH = [cwd]
+
+objs = DefineGroup('Cybergear', src, depend = ['BSP_USING_CYBERGEAR_MOTOR'], CPPPATH = CPPPATH)
+
+list = os.listdir(cwd)
+for item in list:
+    if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
+        objs = objs + SConscript(os.path.join(item, 'SConscript'))
+
+Return('objs')

+ 613 - 0
projects/etherkit_ethercat_coe/board/ports/Cybergear/cybergear.c

@@ -0,0 +1,613 @@
+/**
+ ****************************(C)SWJTU_ROBOTCON****************************
+ * @file       cybergear.c/h
+ * @brief      小米电机函数库
+ * @note
+ * @history
+ *  Version    Date            Author          Modification
+ *  V1.0.0     1-10-2023       ZDYukino        1. done
+ *
+ @verbatim
+ =========================================================================
+ =========================================================================
+ @endverbatim
+ ****************************(C)SWJTU_ROBOTCON****************************
+ **/
+#include "cybergear.h"
+struct rt_semaphore rx_can0_sem;
+struct rt_semaphore rx_can1_sem;
+struct rt_can_msg txMsg0 = { 0 }; //can发送结构体
+struct rt_can_msg txMsg1 = { 0 }; //can接收结构体
+uint8_t byte[4];
+float mech_pos;
+#define can0_txd()      rt_device_write(can0_dev, 0, &txMsg0, sizeof(txMsg0))  //can发送函数
+#define can1_txd()      rt_device_write(can1_dev, 0, &txMsg1, sizeof(txMsg1))  //can发送函数
+uint32_t Type_ID;    //接收数据电机ID
+MI_Motor mi_motor[2];    //预定义两个电机结构体
+/**
+ * @brief          浮点数转4字节函数
+ * @param[in]      f:浮点数
+ * @retval         4字节数组
+ * @description  : IEEE 754 协议
+ */
+static uint8_t* Float_to_Byte(float f)
+{
+    unsigned long longdata = 0;
+    longdata = *(unsigned long*) &f;
+    byte[0] = (longdata & 0xFF000000) >> 24;
+    byte[1] = (longdata & 0x00FF0000) >> 16;
+    byte[2] = (longdata & 0x0000FF00) >> 8;
+    byte[3] = (longdata & 0x000000FF);
+    return byte;
+}
+
+/**
+ * @brief          小米电机回文16位数据转浮点
+ * @param[in]      x:16位回文
+ * @param[in]      x_min:对应参数下限
+ * @param[in]      x_max:对应参数上限
+ * @param[in]      bits:参数位数
+ * @retval         返回浮点值
+ */
+static float uint16_to_float(uint16_t x, float x_min, float x_max, int bits)
+{
+    uint32_t span = (1 << bits) - 1;
+    float offset = x_max - x_min;
+    return offset * x / span + x_min;
+}
+/**
+ * @brief          小米电机发送浮点转16位数据
+ * @param[in]      x:浮点
+ * @param[in]      x_min:对应参数下限
+ * @param[in]      x_max:对应参数上限
+ * @param[in]      bits:参数位数
+ * @retval         返回浮点值
+ */
+
+static int float_to_uint(float x, float x_min, float x_max, int bits)
+{
+    float span = x_max - x_min;
+    float offset = x_min;
+    if (x > x_max)
+        x = x_max;
+    else if (x < x_min)
+        x = x_min;
+    return (int) ((x - offset) * ((float) ((1 << bits) - 1)) / span);
+}
+/**
+ * @brief          写入电机参数 对应模式为 :速度,位置,扭矩
+ * @param[in]      Motor:对应控制电机结构体
+ * @param[in]      Index:写入参数对应地址
+ * @param[in]      Value:写入参数值
+ * @param[in]      Value_type:写入参数数据类型
+ * @retval         none
+ */
+static void Set_Motor_Parameter(MI_Motor *Motor, uint16_t Index, float Value, char Value_type, rt_uint8_t device_type)
+{
+
+    if (device_type == DEVICE_OF_CAN0)
+    {
+        txMsg0.id = 0;
+        txMsg0.id = Communication_Type_SetSingleParameter << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg0.data[0] = Index;
+        txMsg0.data[1] = Index >> 8;
+        txMsg0.data[2] = 0x00;
+        txMsg0.data[3] = 0x00;
+        if (Value_type == 'f')
+        {
+            Float_to_Byte(Value);
+            txMsg0.data[4] = byte[3];
+            txMsg0.data[5] = byte[2];
+            txMsg0.data[6] = byte[1];
+            txMsg0.data[7] = byte[0];
+        }
+        else if (Value_type == 's')
+        {
+            txMsg0.data[4] = (uint8_t) Value;
+            txMsg0.data[5] = 0x00;
+            txMsg0.data[6] = 0x00;
+            txMsg0.data[7] = 0x00;
+        }
+        can0_txd();
+    }
+    else if (device_type == DEVICE_OF_CAN1)
+    {
+        txMsg1.id = 0;
+        txMsg1.id = Communication_Type_SetSingleParameter << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg1.data[0] = Index;
+        txMsg1.data[1] = Index >> 8;
+        txMsg1.data[2] = 0x00;
+        txMsg1.data[3] = 0x00;
+        if (Value_type == 'f')
+        {
+            Float_to_Byte(Value);
+            txMsg1.data[4] = byte[3];
+            txMsg1.data[5] = byte[2];
+            txMsg1.data[6] = byte[1];
+            txMsg1.data[7] = byte[0];
+        }
+        else if (Value_type == 's')
+        {
+            txMsg1.data[4] = (uint8_t) Value;
+            txMsg1.data[5] = 0x00;
+            txMsg1.data[6] = 0x00;
+            txMsg1.data[7] = 0x00;
+        }
+        can1_txd();
+    }
+    rt_thread_mdelay(10);
+}
+
+/**
+ * @brief          提取电机回复帧扩展ID中的Type
+ * @param[in]      CAN_ID_Frame:电机回复帧中的扩展CANID
+ * @retval         Type mode
+ */
+uint32_t Get_Type_Mode(uint32_t CAN_ID_Frame)
+{
+    return (CAN_ID_Frame & 0xFFFFFFFF) >> 24;
+}
+/**
+ * @brief          提取电机回复帧扩展ID中的电机CANID
+ * @param[in]      CAN_ID_Frame:电机回复帧中的扩展CANID
+ * @retval         电机CANID
+ */
+uint32_t Get_Motor_ID(uint32_t CAN_ID_Frame)
+{
+    return (CAN_ID_Frame & 0xFFFF) >> 8;
+
+}
+float ieee_4byte_to_float(const uint8_t bytes[4])
+{
+    // 使用内存拷贝将4字节数组转为float(IEEE 754标准)
+    float value = 0;
+    memcpy(&value, bytes, sizeof(float));
+    return value;
+}
+/**
+ * @brief          电机回复帧数据处理函数
+ * @param[in]      Motor:对应控制电机结构体
+ * @param[in]      DataFrame:数据帧
+ * @param[in]      IDFrame:扩展ID帧
+ * @retval         None
+ */
+void Motor_Data_Handler(MI_Motor *Motor, uint8_t DataFrame[8], uint32_t IDFrame)
+{
+    Motor->Angle = uint16_to_float(DataFrame[0] << 8 | DataFrame[1], MIN_P, MAX_P, 16);
+    Motor->Speed = uint16_to_float(DataFrame[2] << 8 | DataFrame[3], V_MIN, V_MAX, 16);
+    Motor->Torque = uint16_to_float(DataFrame[4] << 8 | DataFrame[5], T_MIN, T_MAX, 16);
+    Motor->Temp = (DataFrame[6] << 8 | DataFrame[7]) * Temp_Gain;
+    Motor->error_code = (IDFrame & 0x1F0000) >> 16;
+    if (Motor->error_code == 1)
+    {
+        rt_kprintf("Error Code:0x%x\n", Motor->error_code);
+        rt_pin_write(LED_PIN_G, PIN_HIGH); //电机出现异常,关闭rgb green
+    }
+}
+/**
+ * @brief          电机回复帧数据处理函数
+ * @param[in]      Motor:对应控制电机结构体
+ * @param[in]      DataFrame:数据帧
+ * @param[in]      IDFrame:扩展ID帧
+ * @retval         None
+ */
+void MechPos_Data_Handler(MI_Motor *Motor, uint8_t DataFrame[8], uint32_t IDFrame)
+{
+    rt_uint8_t dataFrame[4] = { 0 };
+    dataFrame[0] = DataFrame[4];
+    dataFrame[1] = DataFrame[5];
+    dataFrame[2] = DataFrame[6];
+    dataFrame[3] = DataFrame[7];
+    if ((DataFrame[1] << 8 | DataFrame[0]) == 0X7019)
+    {
+        Motor->MechPos = ieee_4byte_to_float(dataFrame);
+    }
+    if ((DataFrame[1] << 8 | DataFrame[0]) == 0X701B)
+    {
+        /* code */
+        Motor->MechVel = ieee_4byte_to_float(dataFrame);
+    }
+    if ((DataFrame[1] << 8 | DataFrame[0]) == 0X7006)
+    {
+        Motor->Iq_ref = ieee_4byte_to_float(dataFrame);
+    }
+
+}
+/**
+ * @brief          小米电机ID检查
+ * @param[in]      id:  控制电机CAN_ID【出厂默认0x7F】
+ * @retval         none
+ */
+void chack_cybergear(uint8_t ID)
+{
+    txMsg0.id = Communication_Type_GetID << 24 | Master_CAN_ID << 8 | ID;
+    can0_txd();
+}
+
+/**
+ * @brief          使能小米电机
+ * @param[in]      Motor:对应控制电机结构体
+ * @retval         none
+ */
+void start_cybergear(MI_Motor *Motor, rt_uint8_t device_type)
+{
+
+    if (device_type == DEVICE_OF_CAN0)
+    {
+        txMsg0.id = 0;
+        txMsg0.id = Communication_Type_MotorEnable << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg0.data[0] = 0x00;
+        txMsg0.data[1] = 0x00;
+        txMsg0.data[2] = 0x00;
+        txMsg0.data[3] = 0x00;
+        txMsg0.data[4] = 0x00;
+        txMsg0.data[5] = 0x00;
+        txMsg0.data[6] = 0x00;
+        txMsg0.data[7] = 0x00;
+        can0_txd();
+    }
+    else if (device_type == DEVICE_OF_CAN1)
+    {
+        txMsg1.id = 0;
+        txMsg1.id = Communication_Type_MotorEnable << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg1.data[0] = 0x00;
+        txMsg1.data[1] = 0x00;
+        txMsg1.data[2] = 0x00;
+        txMsg1.data[3] = 0x00;
+        txMsg1.data[4] = 0x00;
+        txMsg1.data[5] = 0x00;
+        txMsg1.data[6] = 0x00;
+        txMsg1.data[7] = 0x00;
+        can1_txd();
+    }
+}
+
+/**
+ * @brief          停止电机
+ * @param[in]      Motor:对应控制电机结构体
+ * @param[in]      clear_error:清除错误位(0 不清除 1清除)
+ * @retval         None
+ */
+void stop_cybergear(MI_Motor *Motor, uint8_t clear_error, rt_uint8_t device_type)
+{
+
+    if (device_type == DEVICE_OF_CAN0)
+    {
+        txMsg0.data[0] = clear_error;
+        txMsg0.data[1] = 0x00;
+        txMsg0.data[2] = 0x00;
+        txMsg0.data[3] = 0x00;
+        txMsg0.data[4] = 0x00;
+        txMsg0.data[5] = 0x00;
+        txMsg0.data[6] = 0x00;
+        txMsg0.data[7] = 0x00;
+        txMsg0.id = 0;
+        txMsg0.id = Communication_Type_MotorStop << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        can0_txd();
+    }
+    else if (device_type == DEVICE_OF_CAN1)
+    {
+        txMsg1.data[0] = clear_error;
+        txMsg1.data[1] = 0x00;
+        txMsg1.data[2] = 0x00;
+        txMsg1.data[3] = 0x00;
+        txMsg1.data[4] = 0x00;
+        txMsg1.data[5] = 0x00;
+        txMsg1.data[6] = 0x00;
+        txMsg1.data[7] = 0x00;
+        txMsg1.id = 0;
+        txMsg1.id = Communication_Type_MotorStop << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        can1_txd();
+    }
+
+}
+
+/**
+ * @brief          设置电机模式(必须停止时调整!)
+ * @param[in]      Motor:  电机结构体
+ * @param[in]      Mode:   电机工作模式(1.运动模式Motion_mode 2. 位置模式Position_mode 3. 速度模式Speed_mode 4. 电流模式Current_mode)
+ * @retval         none
+ */
+void set_mode_cybergear(MI_Motor *Motor, uint8_t Mode, rt_uint8_t device_type)
+{
+    stop_cybergear(Motor, 1, device_type);
+    rt_thread_mdelay(10);
+    Set_Motor_Parameter(Motor, Run_mode, Mode, 's', device_type);
+    rt_thread_mdelay(10);
+    start_cybergear(Motor, device_type);
+    rt_thread_mdelay(10);
+}
+
+/**
+ * @brief          位置控制模式下设置位置
+ * @param[in]      Motor:  电机结构体
+ * @param[in]      position:目标位置
+ * @retval         none
+ */
+void set_position_cybergear(MI_Motor *Motor, float position, float max_speed, float limit_current, float kp,
+        rt_uint8_t device_type)
+{
+    Set_Motor_Parameter(Motor, Limit_Spd, max_speed, 'f', device_type);
+    //Set_Motor_Parameter(Motor,Limit_Cur,limit_current,'f');
+    Set_Motor_Parameter(Motor, Loc_Kp, kp, 'f', device_type);
+    Set_Motor_Parameter(Motor, Loc_Ref, position, 'f', device_type);
+
+}
+
+/**
+ * @brief          速度控制模式下设置速度
+ * @param[in]      Motor:  电机结构体
+ * @param[in]      speed:目标速度
+ * @retval         none
+ */
+void set_speed_cybergear(MI_Motor *Motor, float speed, rt_uint8_t device_type)
+{
+    Set_Motor_Parameter(Motor, Spd_Ref, speed, 'f', device_type);
+}
+
+/**
+ * @brief          电流控制模式下设置电流
+ * @param[in]      Motor:  电机结构体
+ * @param[in]      Current:电流设置
+ * @retval         none
+ */
+void set_current_cybergear(MI_Motor *Motor, float Current, rt_uint8_t device_type)
+{
+    Set_Motor_Parameter(Motor, Iq_Ref, Current, 'f', device_type);
+    rt_thread_mdelay(10);
+}
+/**
+ * @brief          设置电机零点
+ * @param[in]      Motor:  电机结构体
+ * @retval         none
+ */
+
+void set_zeropos_cybergear(MI_Motor *Motor, rt_uint8_t device_type)
+{
+
+    if (device_type == DEVICE_OF_CAN0)
+    {
+        txMsg0.id = 0;
+        txMsg0.id = Communication_Type_SetPosZero << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg0.data[0] = 0x01;
+        txMsg0.data[1] = 0x00;
+        txMsg0.data[2] = 0x00;
+        txMsg0.data[3] = 0x00;
+        txMsg0.data[4] = 0x00;
+        txMsg0.data[5] = 0x00;
+        txMsg0.data[6] = 0x00;
+        txMsg0.data[7] = 0x00;
+        can0_txd();
+    }
+    else if (device_type == DEVICE_OF_CAN1)
+    {
+        txMsg1.id = 0;
+        txMsg1.id = Communication_Type_SetPosZero << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg1.data[0] = 0x01;
+        txMsg1.data[1] = 0x00;
+        txMsg1.data[2] = 0x00;
+        txMsg1.data[3] = 0x00;
+        txMsg1.data[4] = 0x00;
+        txMsg1.data[5] = 0x00;
+        txMsg1.data[6] = 0x00;
+        txMsg1.data[7] = 0x00;
+        can1_txd();
+    }
+    else
+    {
+        rt_kprintf("device type param error:%d\r\n", device_type);
+    }
+}
+
+/**
+ * @brief          设置电机CANID
+ * @param[in]      Motor:  电机结构体
+ * @param[in]      Motor:  设置新ID
+ * @retval         none
+ */
+void set_CANID_cybergear(MI_Motor *Motor, uint8_t CAN_ID)
+{
+    txMsg0.id = Communication_Type_CanID << 24 | CAN_ID << 16 | Master_CAN_ID << 8 | Motor->CAN_ID;
+    Motor->CAN_ID = CAN_ID;
+    can0_txd();
+}
+/**
+ * @brief          小米电机初始化
+ * @param[in]      Motor:  电机结构体
+ * @param[in]      Can_Id: 小米电机ID(默认0x7F)
+ * @param[in]      Motor_Num: 电机编号
+ * @param[in]      mode: 电机工作模式(0.运动模式Motion_mode 1. 位置模式Position_mode 2. 速度模式Speed_mode 3. 电流模式Current_mode)
+ * @retval         none
+ */
+void init_cybergear(MI_Motor *Motor, uint8_t Can_Id, uint8_t mode, rt_uint8_t device_type)
+{
+    Motor->CAN_ID = Can_Id;
+    set_mode_cybergear(Motor, mode, device_type);
+}
+
+/**
+ * @brief          小米运控模式指令
+ * @param[in]      Motor:  目标电机结构体
+ * @param[in]      torque: 力矩设置[-12,12] N*M
+ * @param[in]      MechPosition: 位置设置[-12.5,12.5] rad
+ * @param[in]      speed: 速度设置[-30,30] rpm
+ * @param[in]      kp: 比例参数设置
+ * @param[in]      kd: 微分参数设置
+ * @retval         none
+ */
+void motor_controlmode(MI_Motor *Motor, float torque, float MechPosition, float speed, float kp, float kd,
+        rt_uint8_t device_type)
+{
+
+    if (device_type == DEVICE_OF_CAN0)
+    {
+        txMsg0.data[0] = float_to_uint(MechPosition, P_MIN, P_MAX, 16) >> 8;
+        txMsg0.data[1] = float_to_uint(MechPosition, P_MIN, P_MAX, 16);
+        txMsg0.data[2] = float_to_uint(speed, V_MIN, V_MAX, 16) >> 8;
+        txMsg0.data[3] = float_to_uint(speed, V_MIN, V_MAX, 16);
+        txMsg0.data[4] = float_to_uint(kp, KP_MIN, KP_MAX, 16) >> 8;
+        txMsg0.data[5] = float_to_uint(kp, KP_MIN, KP_MAX, 16);
+        txMsg0.data[6] = float_to_uint(kd, KD_MIN, KD_MAX, 16) >> 8;
+        txMsg0.data[7] = float_to_uint(kd, KD_MIN, KD_MAX, 16);
+        txMsg0.id = Communication_Type_MotionControl << 24 | float_to_uint(torque, T_MIN, T_MAX, 16) << 8
+                | Motor->CAN_ID;
+        can0_txd();
+    }
+    else if (device_type == DEVICE_OF_CAN1)
+    {
+        txMsg1.data[0] = float_to_uint(MechPosition, P_MIN, P_MAX, 16) >> 8;
+        txMsg1.data[1] = float_to_uint(MechPosition, P_MIN, P_MAX, 16);
+        txMsg1.data[2] = float_to_uint(speed, V_MIN, V_MAX, 16) >> 8;
+        txMsg1.data[3] = float_to_uint(speed, V_MIN, V_MAX, 16);
+        txMsg1.data[4] = float_to_uint(kp, KP_MIN, KP_MAX, 16) >> 8;
+        txMsg1.data[5] = float_to_uint(kp, KP_MIN, KP_MAX, 16);
+        txMsg1.data[6] = float_to_uint(kd, KD_MIN, KD_MAX, 16) >> 8;
+        txMsg1.data[7] = float_to_uint(kd, KD_MIN, KD_MAX, 16);
+        txMsg1.id = Communication_Type_MotionControl << 24 | float_to_uint(torque, T_MIN, T_MAX, 16) << 8
+                | Motor->CAN_ID;
+        can1_txd();
+    }
+    else
+    {
+        rt_kprintf("device type param error:%d\r\n", device_type);
+    }
+}
+/**
+ * @brief          单个参数读取
+ * @param[in]      Motor:  电机结构体
+ * @param[in]      index:  索引号
+ * @retval         none
+ */
+void motor_param_read(MI_Motor *Motor, uint16_t Index, rt_uint8_t device_type)
+{
+    if (device_type == DEVICE_OF_CAN0)
+    {
+        txMsg0.id = 0;
+        txMsg0.id = Communication_Type_GetSingleParameter << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg0.data[0] = Index;
+        txMsg0.data[1] = Index >> 8;
+        txMsg0.data[2] = 0x00;
+        txMsg0.data[3] = 0x00;
+        txMsg0.data[4] = 0x00;
+        txMsg0.data[5] = 0x00;
+        txMsg0.data[6] = 0x00;
+        txMsg0.data[7] = 0x00;
+        can0_txd();
+    }
+    else if (device_type == DEVICE_OF_CAN1)
+    {
+        txMsg1.id = 0;
+        txMsg1.id = Communication_Type_GetSingleParameter << 24 | Master_CAN_ID << 8 | Motor->CAN_ID;
+        txMsg1.data[0] = Index;
+        txMsg1.data[1] = Index >> 8;
+        txMsg1.data[2] = 0x00;
+        txMsg1.data[3] = 0x00;
+        txMsg1.data[4] = 0x00;
+        txMsg1.data[5] = 0x00;
+        txMsg1.data[6] = 0x00;
+        txMsg1.data[7] = 0x00;
+        can1_txd();
+    }
+    else
+    {
+        rt_kprintf("device type param error:%d\r\n", device_type);
+    }
+    rt_thread_mdelay(10);
+}
+static rt_err_t can0_rx_call(rt_device_t dev, rt_size_t size)
+{
+    rt_sem_release(&rx_can0_sem);
+    return RT_EOK;
+}
+static rt_err_t can1_rx_call(rt_device_t dev, rt_size_t size)
+{
+    rt_sem_release(&rx_can1_sem);
+    return RT_EOK;
+}
+/*****************************回调函数 负责接回传信息 可转移至别处*****************************/
+/**
+ * @brief          hal库CAN回调函数,接收电机数据
+
+ * @param[in]      hcan:CAN句柄指针
+ * @retval         none
+ */
+void can0_rx_thread(void *parameter)
+{
+    struct rt_can_msg rxmsg = { 0 };
+
+    rt_device_set_rx_indicate(can0_dev, can0_rx_call);
+    while (1)
+    {
+        if (rt_sem_take(&rx_can0_sem, RT_WAITING_FOREVER) == RT_EOK)
+        {
+            rxmsg.hdr_index = -1;
+            rxmsg.len = 8;
+//            rt_sem_take(&rx_can0_sem, RT_WAITING_FOREVER);
+            rt_device_read(can0_dev, 0, &rxmsg, sizeof(rxmsg));
+            Type_ID = Get_Type_Mode(rxmsg.id); //首先获取回传电机ID信息
+            switch (Type_ID)
+            //将对应ID电机信息提取至对应结构体
+            {
+            //类型为MechPos参数读取返回帧,
+            case 0X11:
+                MechPos_Data_Handler(&mi_motor[0], rxmsg.data, rxmsg.id);
+                //type 类型为 2 的返回帧获取current 速度
+                break;
+            case 0X02:
+                Motor_Data_Handler(&mi_motor[0], rxmsg.data, rxmsg.id);
+                break;
+            default:
+                break;
+            }
+//               rt_kprintf("ID:%x\r\n", rxmsg.id);
+            //   for (rt_uint8_t i = 0; i < 8; i++)
+            //   {
+            //       rt_kprintf("data[%d]:%x\r\n", i,rxmsg.data[i]);
+            //   }
+
+            //  rt_kprintf("\n");
+        }
+    }
+}
+/**
+ * @brief          hal库CAN回调函数,接收电机数据
+
+ * @param[in]      hcan:CAN句柄指针
+ * @retval         none
+ */
+void can1_rx_thread(void *parameter)
+{
+    struct rt_can_msg rxmsg = { 0 };
+
+    rt_device_set_rx_indicate(can1_dev, can1_rx_call);
+
+    while (1)
+    {
+        rxmsg.hdr_index = -1;
+        rxmsg.len = 8;
+        rt_sem_take(&rx_can1_sem, RT_WAITING_FOREVER);
+        rt_device_read(can1_dev, 0, &rxmsg, sizeof(rxmsg));
+        Type_ID = Get_Type_Mode(rxmsg.id);            //首先获取回传电机ID信息
+        switch (Type_ID)
+        //将对应ID电机信息提取至对应结构体
+        {
+        //类型为MechPos参数读取返回帧,
+        case 0X11:
+            MechPos_Data_Handler(&mi_motor[1], rxmsg.data, rxmsg.id);
+            //type 类型为 2 的返回帧获取current 速度        
+            break;
+        case 0X02:
+            Motor_Data_Handler(&mi_motor[1], rxmsg.data, rxmsg.id);
+            break;
+        default:
+            break;
+        }
+        //   rt_kprintf("ID:%x\r\n", rxmsg.id);
+        //   for (rt_uint8_t i = 0; i < 8; i++)
+        //   {
+        //       rt_kprintf("data[%d]:%x\r\n", i,rxmsg.data[i]);
+        //   }
+
+        //  rt_kprintf("\n");
+    }
+}

+ 144 - 0
projects/etherkit_ethercat_coe/board/ports/Cybergear/cybergear.h

@@ -0,0 +1,144 @@
+/**
+  ****************************(C)SWJTU_ROBOTCON****************************
+  * @file       cybergear.c/h
+  * @brief      小米电机函数库
+  * @note       
+  * @history
+  *  Version    Date            Author          Modification
+  *  V1.0.0     1-10-2023       ZDYukino        1. done
+  *
+  @verbatim
+  =========================================================================
+  =========================================================================
+  @endverbatim
+  ****************************(C)SWJTU_ROBOTCON****************************
+  **/
+#ifndef __CYBERBERBER_H__
+#define __CYBERBERBER_H__
+
+#include "rtdevice.h"
+#include "rtthread.h"
+#include "board.h"
+#define LED_PIN_G BSP_IO_PORT_14_PIN_1 /* Onboard GREEN LED pins */
+
+#define P_MIN -12.5f
+#define P_MAX 12.5f
+#define V_MIN -1.0f
+#define V_MAX 1.0f
+#define KP_MIN 0.0f
+#define KP_MAX 500.0f
+#define KD_MIN 0.0f
+#define KD_MAX 5.0f
+#define T_MIN -12.0f
+#define T_MAX 12.0f
+#define MAX_P 720
+#define MIN_P -720
+#define LEADER_FOLLOWER_GAIN   1.0f
+#define Master_CAN_ID         0x01                  
+//通信类型指令定义
+#define Communication_Type_GetID 0x00           //获取设备的 ID 和 64 位 MCU 唯一标识符
+#define Communication_Type_MotionControl 0x01 	  //运控模式电机控制指令 (通信类型 1)用来向电机发送控制指
+#define Communication_Type_MotorRequest 0x02	 //电机反馈数据 用来向主机反馈电机运行状态
+#define Communication_Type_MotorEnable 0x03	    //电机使能运行
+#define Communication_Type_MotorStop 0x04	    //电机停止运行
+#define Communication_Type_SetPosZero 0x06	     //设置电机机械零位
+#define Communication_Type_CanID 0x07	        //设置电机 CAN_ID(通信类型 7)更改当前电机 CAN_ID , 立即生效
+#define Communication_Type_Control_Mode 0x12   //
+#define Communication_Type_GetSingleParameter 0x11	//单个参数读取
+#define Communication_Type_SetSingleParameter 0x12	//单个参数写入
+#define Communication_Type_ErrorFeedback 0x15	    //故障反馈
+
+#define Run_mode 0x7005	           // index of  run mode 
+#define Iq_Ref   0x7006            // index of  Iq_Ref 电流模式 Iq 指令
+#define Spd_Ref  0x700A            // index of  Spd_Ref 转速模式转速指令
+#define Limit_Torque 0x700B       // index of  Limit_Torque  转矩限制
+#define Cur_Kp 0x7010           // index of  Cur_Kp 电流的 Kp
+#define Cur_Ki 0x7011          // index of  Cur_Ki 电流的 Ki
+#define Cur_Filt_Gain 0x7014    // index of  Cur_Filt_Gain 电流的滤波系数
+#define Loc_Ref 0x7016         // index of  Loc_Ref 位置模式角度指令
+#define Loc_Kp 0x701E          // index of  Loc_Kp 位置模式的 Kp
+#define Limit_Spd 0x7017        // index of  Limit_Spd  位置模式速度限制
+#define Limit_Cur 0x7018        // index of  Limit_Cur  速度位置模式电流限制
+#define Mech_Pos 0x7019        // index of  Mech_Pos  负载端计圈机械角度
+#define  Iqf      0x701A         // index of  Iqf  iq 滤波值
+#define  mechVel      0x701B       //   负载端的转速
+#define Gain_Angle 720/32767.0       
+//参数宏定义
+#define Bias_Angle 0x8000          
+#define Gain_Speed 30/32767.0 
+#define Bias_Speed 0x8000             
+#define Gain_Torque 12/32767.0
+#define Bias_Torque 0x8000
+#define Temp_Gain   0.1
+
+#define Motor_Error 0x00
+#define Motor_OK 0X01
+#define CAN0_DEV_NAME       "canfd0"    
+#define CAN1_DEV_NAME       "canfd1"     
+#define DEVICE_OF_CAN0       0x00
+#define DEVICE_OF_CAN1       0X01
+extern rt_thread_t thread;
+extern rt_device_t can0_dev;
+extern rt_device_t can1_dev;
+extern struct rt_semaphore rx_can0_sem;
+extern struct rt_semaphore rx_can1_sem;
+extern struct rt_can_msg txMsg0 ;
+extern struct rt_can_msg txMsg1 ;
+extern struct rt_can_msg rxMsg ;
+
+//控制模式定义结构体
+enum CONTROL_MODE    
+{
+    Motion_mode = 0,
+    Position_mode,  
+    Velocity_mode,     
+    Current_mode    
+};
+//故障类型定义
+enum ERROR_TAG     
+{
+    OK                 = 0, //无故障
+    BAT_LOW_ERR        = 1, //电池低电压故障
+    OVER_CURRENT_ERR   = 2, //过流故障
+    OVER_TEMP_ERR      = 3,//过温
+    MAGNETIC_ERR       = 4, //磁编码故障
+    HALL_ERR_ERR       = 5, //霍尔编码故障
+    NO_CALIBRATION_ERR = 6 //预定义
+};
+//电机结构体
+typedef struct{           
+	uint8_t CAN_ID;       //can id 
+    uint8_t MCU_ID;       //mcu id 标识符
+	float Angle;          //回传角度
+	float Speed;          //回传速度
+	float Torque;        //回传力矩
+	float Temp;			  //回传温度
+	uint16_t set_current;  
+	uint16_t set_speed;
+	uint16_t set_position;
+	
+	uint8_t error_code;
+	float  MechPos;
+    float  MechVel;
+	float Angle_Bias;
+    float Iq_ref;
+	float  current_iq;
+}MI_Motor;
+extern MI_Motor mi_motor[2];
+
+extern void chack_cybergear(uint8_t ID);
+extern void start_cybergear(MI_Motor *Motor,rt_uint8_t device_type);
+extern void stop_cybergear(MI_Motor *Motor, uint8_t clear_error,rt_uint8_t device_type);
+extern void set_mode_cybergear(MI_Motor *Motor, uint8_t Mode,rt_uint8_t device_type);
+extern void set_current_cybergear(MI_Motor *Motor, float Current,rt_uint8_t device_type);
+extern void set_zeropos_cybergear(MI_Motor *Motor,rt_uint8_t device_type);
+extern void set_CANID_cybergear(MI_Motor *Motor, uint8_t CAN_ID);
+extern void init_cybergear(MI_Motor *Motor, uint8_t Can_Id, uint8_t mode,rt_uint8_t device_type);
+extern void motor_controlmode(MI_Motor *Motor,float torque, float MechPosition, float speed, float kp, float kd,rt_uint8_t device_type);
+extern void set_position_cybergear(MI_Motor *Motor, float position, float max_speed, float limit_current , float kp,rt_uint8_t device_type);
+extern void set_speed_cybergear(MI_Motor *Motor, float speed,rt_uint8_t device_type);
+extern void motor_param_read(MI_Motor *Motor,uint16_t Index,rt_uint8_t device_type);
+extern uint32_t Get_Type_Mode(uint32_t CAN_ID_Frame);
+extern void can0_rx_thread(void *parameter);
+extern void can1_rx_thread(void *parameter);
+#endif

+ 290 - 0
projects/etherkit_ethercat_coe/board/ports/Cybergear/cybergearapp.c

@@ -0,0 +1,290 @@
+#include "cybergear.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+static rt_timer_t timer1;
+rt_thread_t thread_can0;
+rt_thread_t thread_can1;
+rt_device_t can0_dev;
+rt_device_t can1_dev;
+uint32_t Motor_Can_ID;    //接收数据电机ID
+static rt_sem_t mechPos_read_sem = RT_NULL;
+static void motor_init();
+void read_poch_thread(void *parameter);
+static void timer_init(void);
+void read_poch(void);
+void speed_print_thread(void *parameter);
+static void can_init(void);
+void motor2_init_thread(void *parameter);
+int cybergearapp_init(void)
+{
+    timer_init();
+    can_init();
+    read_poch();
+    motor_init();
+    return 0;
+}
+//can0 can1初始化
+static void can_init(void)
+{
+    rt_uint8_t res;
+    can0_dev = rt_device_find(CAN0_DEV_NAME);
+    if (!can0_dev)
+    {
+        rt_kprintf("find %s failed!\n", CAN0_DEV_NAME);
+        return;
+    }
+    can1_dev = rt_device_find(CAN1_DEV_NAME);
+    if (!can1_dev)
+    {
+        rt_kprintf("find %s failed!\n", CAN1_DEV_NAME);
+        return;
+    }
+    res = rt_device_open(can0_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
+    res = rt_device_control(can0_dev, RT_CAN_CMD_SET_BAUD, (void *) CAN1MBaud);
+    res = rt_device_open(can1_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
+    res = rt_device_control(can1_dev, RT_CAN_CMD_SET_BAUD, (void *) CAN1MBaud);
+    RT_ASSERT(res == RT_EOK);
+    rt_sem_init(&rx_can0_sem, "rx_can0_sem", 0, RT_IPC_FLAG_FIFO);
+    rt_sem_init(&rx_can1_sem, "rx_can1_sem", 0, RT_IPC_FLAG_FIFO);
+    thread_can0 = rt_thread_create("can0_rx", can0_rx_thread, RT_NULL, 1024, 10, 50);
+    if (thread_can0 != RT_NULL)
+    {
+        rt_thread_startup(thread_can0);
+    }
+    else
+    {
+        rt_kprintf("create can_rx thread failed!\n");
+    }
+    thread_can1 = rt_thread_create("can1_rx", can1_rx_thread, RT_NULL, 1024, 25, 10);
+    if (thread_can1 != RT_NULL)
+    {
+        rt_thread_startup(thread_can1);
+    }
+    else
+    {
+        rt_kprintf("create can1_rx thread failed!\n");
+    }
+
+}
+/* 定时器 超时函数,定时读取电机参数 */
+static void timer_100ms_callback(void *parameter)
+{
+    rt_sem_release(mechPos_read_sem);
+}
+static void timer_init(void)
+{
+    mechPos_read_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO);
+    timer1 = rt_timer_create("timer1", timer_100ms_callback,
+    RT_NULL, 10,
+    RT_TIMER_FLAG_PERIODIC);
+    /* 启动定时器 1 */
+    if (timer1 != RT_NULL)
+        rt_timer_start(timer1);
+}
+//电机初始化,默认电机ID 为0X7F
+static void motor_init()
+{
+    txMsg0.id = 0;
+    txMsg0.ide = RT_CAN_EXTID;
+    txMsg0.rtr = RT_CAN_DTR;
+    txMsg0.len = 8;
+    txMsg1.id = 0;
+    txMsg1.ide = RT_CAN_EXTID;
+    txMsg1.rtr = RT_CAN_DTR;
+    txMsg1.len = 8;
+    mi_motor[1].CAN_ID = 0x7f;
+    mi_motor[0].CAN_ID = 0x7f;
+}
+/**
+ * @brief          设置电机模式;
+ * @param[in]      argv[1]:  模式选择 0 -->运控 1-->位置 2-->速度 ,3-->电流
+ * @param[in]      argv[2]:  电机索引index 0代表电机1 使用can0接口
+ * @retval         none
+ */
+void cybergearapp_set_mode(int argc, char *argv[])
+{
+    if (argc != 3)
+    {
+        rt_kprintf("Usage: set_mode <mode>\n");
+        return;
+    }
+    int mode = atoi(argv[1]);
+    int device_type = atoi(argv[2]);
+    switch (mode)
+    {
+    case 0:
+        init_cybergear(&mi_motor[1], 0x7f, Motion_mode, device_type);
+        rt_kprintf("Setting mode Motion_mode\r\n");
+        break;
+    case 1:
+        init_cybergear(&mi_motor[1], 0x7f, Position_mode, device_type);
+        rt_kprintf("Setting mode Position_mode\r\n");
+        break;
+    case 2:
+        init_cybergear(&mi_motor[1], 0x7f, Velocity_mode, device_type);
+        rt_kprintf("Setting mode Velocity_mode\r\n");
+        break;
+    case 3:
+        init_cybergear(&mi_motor[1], 0x7f, Current_mode, device_type);
+
+        rt_kprintf("Setting mode Current_mode\r\n");
+    default:
+        rt_kprintf("please choose the correct mode!\r\n");
+
+    }
+    return;
+}
+
+/**
+ * @brief          位置模式测试函数
+ * @param[in]      argv[1]:  位移目标值
+ * @param[in]      argv[2]:  电机索引index 0代表电机1 使用can0接口
+ * @retval         none
+ */
+void test_motor_position(int argc, char *argv[])
+{
+    if (argc < 2)
+    {
+        printf("Usage: test_motor <position>\n");
+        return;
+    }
+    // 打印字符串参数
+    printf("argv[%d]: %s\n", 1, argv[1]);
+    rt_uint8_t device_type = atoi(argv[2]);
+    // 正确转换字符串为浮点数
+    char *endptr;
+    float value = strtof(argv[1], &endptr);
+    // 检查转换是否成功
+    if (*endptr != '\0')
+    {
+        printf("Invalid float value: %s\n", argv[1]);
+        return;
+    }
+    // 调用电机控制函数
+    set_position_cybergear(&mi_motor[1], value, 5, 8, 40, device_type);
+}
+/**
+ * @brief          速度模式测试函数
+ * @param[in]      argv[1]:  速度目标值
+ * @param[in]      argv[2]:  电机索引index 0代表电机1 使用can0接口
+ * @retval         none
+ */
+void test_motor_speed(int argc, char *argv[])
+{
+    if (argc < 2)
+    {
+        printf("Usage: test_motor <position>\n");
+        return;
+    }
+    // 打印字符串参数
+    printf("argv[%d]: %s\n", 1, argv[1]);
+    // 正确转换字符串为浮点数
+    char *endptr;
+    float value = strtof(argv[1], &endptr);
+    // 检查转换是否成功
+    if (*endptr != '\0')
+    {
+        printf("Invalid float value: %s\n", argv[1]);
+        return;
+    }
+    rt_uint8_t device_type = atoi(argv[2]);
+    // 打印转换后的浮点数
+    printf("Converted float value: %f\n", value);
+    set_speed_cybergear(&mi_motor[1], value, device_type);
+    rt_thread_mdelay(200);
+}
+
+void speed_print(void)
+{
+    //创建线程
+    rt_thread_t thread;
+    thread = rt_thread_create("speed_print", speed_print_thread, RT_NULL, 1024, 25, 10);
+    if (thread != RT_NULL)
+    {
+        rt_thread_startup(thread);
+    }
+    else
+    {
+        rt_kprintf("create speed_print thread failed!\n");
+    }
+}
+//速度角度测试线程 msh
+void speed_print_thread(void *parameter)
+{
+    static rt_uint8_t result;
+    while (1)
+    {
+        if (result == RT_EOK)
+        {
+            rt_thread_mdelay(3000);
+            printf("Speed0:%f\n", mi_motor[0].Speed);
+            printf("rad0:%f\n", mi_motor[0].Angle);
+        }
+    }
+}
+
+void motor2_init(void)
+{
+    //创建线程
+    rt_thread_t thread;
+    thread = rt_thread_create("motor2_init", motor2_init_thread, RT_NULL, 1024, 25, 10);
+    if (thread != RT_NULL)
+    {
+        rt_thread_startup(thread);
+    }
+    else
+    {
+        rt_kprintf("create motor2_init thread failed!\n");
+    }
+}
+/*电机2设为位置模式跟随电机1*/
+void motor2_init_thread(void *parameter)
+{
+    while (1)
+    {
+        //设置位置函数
+        set_position_cybergear(&mi_motor[1], mi_motor[0].MechPos, mi_motor[0].MechVel, 8, 40, DEVICE_OF_CAN1);
+        rt_thread_mdelay(20);
+    }
+}
+void read_poch(void)
+{
+    //创建线程
+    rt_thread_t thread;
+    thread = rt_thread_create("read_poch", read_poch_thread, RT_NULL, 1024, 25, 10);
+    if (thread != RT_NULL)
+    {
+        rt_thread_startup(thread);
+    }
+    else
+    {
+        rt_kprintf("create read_poch thread failed!\n");
+    }
+}
+//定时读取计圈角度,电流、速度
+void read_poch_thread(void *parameter)
+{
+    static rt_uint8_t result;
+    while (1)
+    {
+        result = rt_sem_take(mechPos_read_sem, RT_WAITING_FOREVER);
+        if (result == RT_EOK)
+        {
+            motor_param_read(&mi_motor[0], Mech_Pos, DEVICE_OF_CAN0);    //读取电机0计圈角度
+            motor_param_read(&mi_motor[0], mechVel, DEVICE_OF_CAN0);    //读取电机0速度
+            motor_param_read(&mi_motor[0], Iq_Ref, DEVICE_OF_CAN0); //读取电机0的电流
+            motor_param_read(&mi_motor[1], Mech_Pos, DEVICE_OF_CAN1); //读取电机1计圈角度
+            motor_param_read(&mi_motor[1], mechVel, DEVICE_OF_CAN1); //读取电机1速度
+        }
+    }
+}
+/* 导出到 msh 命令列表中 */
+MSH_CMD_EXPORT(speed_print, demo);
+MSH_CMD_EXPORT(motor2_init, demo);
+MSH_CMD_EXPORT(read_poch, demo);
+MSH_CMD_EXPORT(test_motor_position, demo);
+MSH_CMD_EXPORT(test_motor_speed, demo);
+MSH_CMD_EXPORT_ALIAS(cybergearapp_set_mode, set_mode, Set the mode of the cybergear);
+INIT_APP_EXPORT(cybergearapp_init);

+ 59 - 2
projects/etherkit_ethercat_coe/board/ports/ethercat/beckhoff/Src/cia402appl.c

@@ -61,7 +61,9 @@ V4.30 : create file (state machine; handling state transition options; input fee
 #define _CiA402_
 #include "cia402appl.h"
 #undef _CiA402_
-
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+#include "cybergear.h"
+#endif
 #include "hal_data.h"
 
 #if (CiA402_SAMPLE_APPLICATION == 1)
@@ -472,8 +474,50 @@ void CiA402_StateMachine(void)
                 if (((ControlWord6040 & CONTROLWORD_COMMAND_SWITCHON_MASK) == CONTROLWORD_COMMAND_SWITCHON) ||
                     ((ControlWord6040 & CONTROLWORD_COMMAND_SWITCHON_ENABLEOPERATION_MASK) == CONTROLWORD_COMMAND_SWITCHON_ENABLEOPERATION))
                 {
-                    if(!CiA402_StateTransition3(pCiA402Axis)){
+                    if(!CiA402_StateTransition3(pCiA402Axis))
+                    {
                         pCiA402Axis->i16State = STATE_SWITCHED_ON;           // Transition 3
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+                        //电机模式初始化
+                        switch (pCiA402Axis->Objects.objModesOfOperationDisplay)
+                        {
+                        case CYCLIC_SYNC_POSITION_MODE:
+                            /* code */
+                            //初始化电机位位置模式
+                            if (counter == 0)
+                            {
+                                //localAxis[0] 位置模式
+                                init_cybergear(&mi_motor[0], 0x7f, Position_mode, DEVICE_OF_CAN0);
+                                rt_kprintf("motor0 position set  to position %d\n", Position_mode);
+                            }
+                            if (counter == 1)
+                            {
+                                //localAxis[1] 位置模式
+                                init_cybergear(&mi_motor[1], 0x7f, Position_mode, DEVICE_OF_CAN1);
+                                rt_kprintf("motor1 position set  to position %d\n", Position_mode);
+                            }
+                            break;
+                        case CYCLIC_SYNC_VELOCITY_MODE:
+                            //init motor Velocity
+                            if (counter == 0)
+                            {
+                                //localAxis[0] 速度模式
+                                init_cybergear(&mi_motor[0], 0x7f, Velocity_mode, DEVICE_OF_CAN0);
+                                set_speed_cybergear(&mi_motor[0], 0, DEVICE_OF_CAN0);
+                                rt_kprintf("motor0 Velocity_mode set  to Velocity %d\n", Velocity_mode);
+                            }
+                            if (counter == 1)
+                            {
+                                //localAxis[1] 速度模式
+                                init_cybergear(&mi_motor[1], 0x7f, Velocity_mode, DEVICE_OF_CAN1);
+                                set_speed_cybergear(&mi_motor[1], 0, DEVICE_OF_CAN1);
+                                rt_kprintf("motor1 Velocity_mode set  to Velocity %d\n", Velocity_mode);
+                            }
+                            break;
+                        default:
+                            break;
+                        }
+#endif
                     }
                 }
                 break;
@@ -497,6 +541,13 @@ void CiA402_StateMachine(void)
                     {
                         if(!CiA402_StateTransition4(pCiA402Axis)){	
                             pCiA402Axis->i16State = STATE_OPERATION_ENABLED;  // Transition 4
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+                    //enable motor
+                    if (counter == 0)
+                        start_cybergear(&mi_motor[0], DEVICE_OF_CAN0);
+                    if (counter == 1)
+                        start_cybergear(&mi_motor[1], DEVICE_OF_CAN1);
+#endif
                         //The Axis function shall be enabled and all internal set-points cleared.
                         }
                     }
@@ -540,6 +591,12 @@ void CiA402_StateMachine(void)
                         {
                             if(!CiA402_StateTransition9(pCiA402Axis)){
                                 pCiA402Axis->i16State = STATE_SWITCH_ON_DISABLED; // Transition 9
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+                    if (counter == 0)
+                        stop_cybergear(&mi_motor[0], 1, DEVICE_OF_CAN0);
+                    if (counter == 1)
+                        stop_cybergear(&mi_motor[1], 1, DEVICE_OF_CAN1);
+#endif
                             }
                         }
                         break;

+ 5 - 1
projects/etherkit_ethercat_coe/board/ports/ethercat/beckhoff/Src/ecatappl.c

@@ -155,7 +155,9 @@ V4.00 APPL 6: The main function was split in MainInit and MainLoop
 #include "hal_data.h"
 #include "samplecia402.h"
 #include "sampleappl.h"
-
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+#include  "cybergear.h"
+#endif
 /*--------------------------------------------------------------------------------------
 ------
 ------    local Types and Defines
@@ -1062,7 +1064,9 @@ void MainLoop(void)
                 HW_ClearTimer();
 
 #if (CiA402_SAMPLE_APPLICATION == 1) && (BSP_CFG_CORE_CR52 == 0)
+#ifndef BSP_USING_CYBERGEAR_MOTOR
                 DummyMotor();
+#endif
 #endif
             }
         }

+ 54 - 1
projects/etherkit_ethercat_coe/board/ports/ethercat/ethercat_coe_app.c

@@ -27,6 +27,17 @@
 static rt_uint8_t ethercat_thread_stack[1024 * 4];
 static struct rt_thread ethercat_thread;
 
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+#include  "cybergear.h"
+#include "samplecia402.h"
+
+static rt_sem_t cyber_sem = RT_NULL;
+static rt_timer_t cyber_timer;
+
+void cyber_motor_entry(void *param);
+static void timer_cyber_init(void);
+#endif
+
 static void ecat_thread_entry ();
 
 void phy_rtl8211f_initial(ether_phy_instance_ctrl_t *phydev)
@@ -82,6 +93,15 @@ static int coe_app(void)
         rt_thread_startup(&ethercat_thread);
     }
 
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+    timer_cyber_init();
+    rt_thread_t cy_tid = rt_thread_create("cyber_motor", cyber_motor_entry, RT_NULL, 1024, 5, 20);
+    if (cy_tid != RT_NULL)
+    {
+        rt_thread_startup(cy_tid);
+    }
+#endif
+
     return 0;
 }
 INIT_APP_EXPORT(coe_app);
@@ -107,7 +127,7 @@ static void ecat_thread_entry ()
     while(bRunApplication == TRUE)
     {
         MainLoop();
-        rt_thread_mdelay(1);
+        rt_thread_mdelay(2);
     }
 #if (CiA402_SAMPLE_APPLICATION == 1)
     /* Remove all allocated axes resources */
@@ -118,3 +138,36 @@ static void ecat_thread_entry ()
 
     return;
 }
+
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+void cyber_motor_entry(void *param)
+{
+    rt_uint8_t result;
+    while (1)
+    {
+        result = rt_sem_take(cyber_sem, RT_WAITING_FOREVER);
+        if (result == RT_EOK)
+        {
+            //电机控制函数
+            CybergearMotor();
+        }
+    }
+}
+
+/* 定时器 1 超时函数 负责定时扫描主站映射数据 */
+static void cyimer_100ms_callback(void *parameter)
+{
+    rt_sem_release(cyber_sem);
+}
+
+static void timer_cyber_init(void)
+{
+    cyber_sem = rt_sem_create("sy_sem", 0, RT_IPC_FLAG_PRIO);
+    cyber_timer = rt_timer_create("sy_timer", cyimer_100ms_callback,
+    RT_NULL, 100,
+    RT_TIMER_FLAG_PERIODIC);
+    /* 启动定时器 1 */
+    if (cyber_timer != RT_NULL)
+        rt_timer_start(cyber_timer);
+}
+#endif

+ 154 - 42
projects/etherkit_ethercat_coe/board/ports/ethercat/renesas/samplecia402.c

@@ -84,55 +84,167 @@ TAxis LocalTAxis[MAX_AXES];
 ------
 -----------------------------------------------------------------------------------------*/
 #if (BSP_CFG_CORE_CR52 == 0)
+#ifndef BSP_USING_CYBERGEAR_MOTOR
 /*******************************************************************************
-* Function Name: DummyMotor
-* Description  : Increment VelocityActualValue
-* Arguments    : none
-* Return Value : none
-*******************************************************************************/
+ * Function Name: DummyMotor
+ * Description  : Increment VelocityActualValue
+ * Arguments    : none
+ * Return Value : none
+ *******************************************************************************/
 void DummyMotor(void)
 {
 
-	TCiA402Axis *pCiA402Axis;
-	uint8_t i;
+    TCiA402Axis *pCiA402Axis;
+    uint8_t i;
 
-	for(i = 0; i < MAX_AXES;i++)
-	{
-		pCiA402Axis = &LocalAxes[i];
-		switch( pCiA402Axis->Objects.objModesOfOperationDisplay )
-		{
-		case CYCLIC_SYNC_POSITION_MODE:
-			if(pCiA402Axis->i16State == STATE_OPERATION_ENABLED)
-			{
-				if(LocalTAxis[i].PositionActualValue < LocalTAxis[i].TargetPosition)
-				{
-					LocalTAxis[i].PositionActualValue++;
-				}
-			}
-			else
-			{
-				LocalTAxis[i].PositionActualValue = 0;
-			}
-			break;
-		case CYCLIC_SYNC_VELOCITY_MODE:
-			if(pCiA402Axis->i16State == STATE_OPERATION_ENABLED)
-			{
-				if(LocalTAxis[i].VelocityActualValue < LocalTAxis[i].TargetVelocity)
-				{
-					LocalTAxis[i].VelocityActualValue++;
-				}
-			}
-			else
-			{
-				LocalTAxis[i].VelocityActualValue = 0;
-			}
-			break;
-		default:
-			break;
-		}
-	}
+    for(i = 0; i < MAX_AXES;i++)
+    {
+        pCiA402Axis = &LocalAxes[i];
+        switch( pCiA402Axis->Objects.objModesOfOperationDisplay )
+        {
+            case CYCLIC_SYNC_POSITION_MODE:
+            if(pCiA402Axis->i16State == STATE_OPERATION_ENABLED)
+            {
+                if(LocalTAxis[i].PositionActualValue < LocalTAxis[i].TargetPosition)
+                {
+                    LocalTAxis[i].PositionActualValue++;
+                }
+            }
+            else
+            {
+                LocalTAxis[i].PositionActualValue = 0;
+            }
+            break;
+            case CYCLIC_SYNC_VELOCITY_MODE:
+            if(pCiA402Axis->i16State == STATE_OPERATION_ENABLED)
+            {
+                if(LocalTAxis[i].VelocityActualValue < LocalTAxis[i].TargetVelocity)
+                {
+                    LocalTAxis[i].VelocityActualValue++;
+                }
+            }
+            else
+            {
+                LocalTAxis[i].VelocityActualValue = 0;
+            }
+            break;
+            default:
+            break;
+        }
+    }
+}
+#else
+static float postion_target = 0;
+/*******************************************************************************
+ * Function Name: CybearMotor
+ * Description  : Increment VelocityActualValue
+ * Arguments    : LocalAxes[0]表示电机num 0 对应硬件canfd0;LocalAxes[1]表示电机num 1 对应硬件canfd2;
+ * Return Value : none
+ *******************************************************************************/
+void CybergearMotor(void)
+{
+    TCiA402Axis *pCiA402Axis;
+    uint8_t i;
+    float vel;
+    for (i = 0; i < MAX_AXES; i++)
+    {
+        pCiA402Axis = &LocalAxes[i];
+        switch (pCiA402Axis->Objects.objModesOfOperationDisplay)
+        {
+        //位置模式
+        case CYCLIC_SYNC_POSITION_MODE:
+            if (pCiA402Axis->i16State == STATE_OPERATION_ENABLED)
+            {
+                postion_target = (float) (LocalTAxis[i].TargetPosition);
+                if (postion_target != 0)
+                {
+                    if (i == 0)
+                        set_position_cybergear(&mi_motor[0], postion_target, 5, 8, 40, DEVICE_OF_CAN0);
+                    if (i == 1)
+                        set_position_cybergear(&mi_motor[1], postion_target, 5, 8, 40, DEVICE_OF_CAN1);
+                }
+                else
+                {
+                    if (i == 0)
+                        set_position_cybergear(&mi_motor[0], 0, 5, 8, 40, DEVICE_OF_CAN0);
+                    if (i == 1)
+                        set_position_cybergear(&mi_motor[1], 0, 5, 8, 40, DEVICE_OF_CAN1);
+                }
+                if (i == 0)
+                {
+                    motor_param_read(&mi_motor[0], Mech_Pos, DEVICE_OF_CAN0);
+                    motor_param_read(&mi_motor[0], mechVel, DEVICE_OF_CAN0);
+                    //分别将计圈机械角度、与速度数据传递给主站Axis 0
+                    LocalTAxis[i].PositionActualValue = (int) roundf(mi_motor[0].MechPos);
+                    LocalTAxis[i].VelocityActualValue = (int) roundf(mi_motor[0].MechVel);
+                }
+                if (i == 1)
+                {
+                    motor_param_read(&mi_motor[1], Mech_Pos, DEVICE_OF_CAN1);
+                    motor_param_read(&mi_motor[1], mechVel, DEVICE_OF_CAN1);
+                    //分别将计圈机械角度、与速度数据传递给主站Axis 1
+                    LocalTAxis[i].PositionActualValue = (int) (mi_motor[1].MechPos);
+                    LocalTAxis[i].VelocityActualValue = (int) (mi_motor[1].MechVel);
+                }
+            }
+            else
+            {
+                LocalTAxis[i].PositionActualValue = 0;
+            }
+            break;
+            //速度模式
+        case CYCLIC_SYNC_VELOCITY_MODE:
+            if (pCiA402Axis->i16State == STATE_OPERATION_ENABLED)
+            {
+                postion_target = (float) (LocalTAxis[i].TargetVelocity);
+                if (postion_target != 0)
+                {
+                    if (i == 0)
+                        set_speed_cybergear(&mi_motor[0], postion_target, DEVICE_OF_CAN0);
+                    if (i == 1)
+                        set_speed_cybergear(&mi_motor[1], postion_target, DEVICE_OF_CAN1);
+                }
+                else
+                {
+                    if (i == 0)
+                        set_speed_cybergear(&mi_motor[0], 2, DEVICE_OF_CAN0);
+                    if (i == 1)
+                        set_speed_cybergear(&mi_motor[1], 2, DEVICE_OF_CAN1);
+                }
+                if (i == 0)
+                {
+                    motor_param_read(&mi_motor[0], Mech_Pos, DEVICE_OF_CAN0);
+                    LocalTAxis[i].PositionActualValue = (int) (roundf(mi_motor[0].MechPos));
+                    if (mi_motor[0].Speed > 0)
+                        vel = mi_motor[0].Speed >= 0.1 ? mi_motor[0].Speed * 100 / 3 - 0.8 : mi_motor[0].Speed * 100 / 3;
+                    else
+                        vel = mi_motor[0].Speed <= -0.1 ? mi_motor[0].Speed * 100 / 3 + 0.8 : mi_motor[0].Speed * 100 / 3;
+                    LocalTAxis[i].VelocityActualValue = (int) roundf(vel);
+                }
+                if (i == 1)
+                {
+                    motor_param_read(&mi_motor[1], Mech_Pos, DEVICE_OF_CAN1);
+                    LocalTAxis[i].PositionActualValue = (int) (mi_motor[1].MechPos);
+                    if (mi_motor[1].Speed > 0)
+                        vel = mi_motor[1].Speed >= 0.1 ? mi_motor[1].Speed * 100 / 3 - 0.8 : mi_motor[1].Speed * 100 / 3;
+                    else
+                        vel = mi_motor[1].Speed <= -0.1 ? mi_motor[1].Speed * 100 / 3 + 0.8 : mi_motor[1].Speed * 100 / 3;
+                    LocalTAxis[i].VelocityActualValue = (int) roundf(vel);
+                }
+            }
+            else
+            {
+                LocalTAxis[i].VelocityActualValue = 0;
+
+            }
+            break;
+        default:
+            break;
+        }
+    }
 }
 #endif
+#endif
 /////////////////////////////////////////////////////////////////////////////////////////
 /**
  \brief    CiA402_DummyMotionControl

+ 3 - 1
projects/etherkit_ethercat_coe/board/ports/ethercat/renesas/samplecia402.h

@@ -31,7 +31,9 @@ V5.01 : Start file change log
 -----------------------------------------------------------------------------------------*/
 #include "ecat_def.h"
 #include "cia402appl.h"
-
+#ifdef BSP_USING_CYBERGEAR_MOTOR
+#include  "cybergear.h"
+#endif
 #if (CiA402_SAMPLE_APPLICATION == 1)
 
 #ifndef _CIA402_SAMPLE_H_

+ 8 - 1
projects/etherkit_ethercat_coe/buildinfo.ipcf

@@ -53,7 +53,7 @@
         <group name="RA Smart Configurator">
             <argVar>
                 <name>RASC_EXE_PATH</name>
-                <value>D:\manufacture_apps\Renesas\fsp\rzn_v2.0.0\eclipse\rasc.exe</value>
+                <value>C:\Renesas\rzn\sc_v2024-01.1_fsp_v2.0.0\eclipse\rasc.exe</value>
             </argVar>
         </group>
     </customArgVars>
@@ -74,6 +74,7 @@
             <path>rzn/board/rzn2l_rsk/board_leds.h</path>
             <path>rzn/fsp/inc/api/bsp_api.h</path>
             <path>rzn/fsp/inc/api/rm_ethercat_ssc_port_api.h</path>
+            <path>rzn/fsp/inc/api/r_can_api.h</path>
             <path>rzn/fsp/inc/api/r_ether_phy_api.h</path>
             <path>rzn/fsp/inc/api/r_ether_selector_api.h</path>
             <path>rzn/fsp/inc/api/r_ioport_api.h</path>
@@ -84,9 +85,11 @@
             <path>rzn/fsp/inc/fsp_features.h</path>
             <path>rzn/fsp/inc/fsp_version.h</path>
             <path>rzn/fsp/inc/instances/rm_ethercat_ssc_port.h</path>
+            <path>rzn/fsp/inc/instances/r_canfd.h</path>
             <path>rzn/fsp/inc/instances/r_cmt.h</path>
             <path>rzn/fsp/inc/instances/r_ether_phy.h</path>
             <path>rzn/fsp/inc/instances/r_ether_selector.h</path>
+            <path>rzn/fsp/inc/instances/r_gpt.h</path>
             <path>rzn/fsp/inc/instances/r_ioport.h</path>
             <path>rzn/fsp/inc/instances/r_sci_uart.h</path>
             <path>rzn/fsp/src/bsp/cmsis/Device/RENESAS/Include/R9A07G084.h</path>
@@ -132,9 +135,11 @@
             <path>rzn/fsp/src/bsp/mcu/rzn2l/bsp_override.h</path>
             <path>rzn/fsp/src/rm_ethercat_ssc_port/renesashw.h</path>
             <path>rzn/fsp/src/rm_ethercat_ssc_port/rm_ethercat_ssc_port.c</path>
+            <path>rzn/fsp/src/r_canfd/r_canfd.c</path>
             <path>rzn/fsp/src/r_cmt/r_cmt.c</path>
             <path>rzn/fsp/src/r_ether_phy/r_ether_phy.c</path>
             <path>rzn/fsp/src/r_ether_selector/r_ether_selector.c</path>
+            <path>rzn/fsp/src/r_gpt/r_gpt.c</path>
             <path>rzn/fsp/src/r_ioport/r_ioport.c</path>
             <path>rzn/fsp/src/r_sci_uart/r_sci_uart.c</path>
             <path>rzn/SConscript</path>
@@ -149,9 +154,11 @@
             <path>rzn_cfg/fsp_cfg/bsp/bsp_memory_cfg.h</path>
             <path>rzn_cfg/fsp_cfg/bsp/bsp_pin_cfg.h</path>
             <path>rzn_cfg/fsp_cfg/rm_ethercat_ssc_port_cfg.h</path>
+            <path>rzn_cfg/fsp_cfg/r_canfd_cfg.h</path>
             <path>rzn_cfg/fsp_cfg/r_cmt_cfg.h</path>
             <path>rzn_cfg/fsp_cfg/r_ether_phy_cfg.h</path>
             <path>rzn_cfg/fsp_cfg/r_ether_selector_cfg.h</path>
+            <path>rzn_cfg/fsp_cfg/r_gpt_cfg.h</path>
             <path>rzn_cfg/fsp_cfg/r_ioport_cfg.h</path>
             <path>rzn_cfg/fsp_cfg/r_sci_uart_cfg.h</path>
             <path>rzn_cfg/SConscript</path>

+ 207 - 13
projects/etherkit_ethercat_coe/configuration.xml

@@ -687,6 +687,14 @@
       <description>EtherCAT Slave Stack Code port for RZ microprocessors</description>
       <originalPack>Renesas.RZN.2.0.0.pack</originalPack>
     </component>
+    <component apiversion="" class="HAL Drivers" condition="" group="all" subgroup="r_canfd" variant="" vendor="Renesas" version="2.0.0">
+      <description>Controller Area Network - Flexible Data</description>
+      <originalPack>Renesas.RZN.2.0.0.pack</originalPack>
+    </component>
+    <component apiversion="" class="HAL Drivers" condition="" group="all" subgroup="r_gpt" variant="" vendor="Renesas" version="2.0.0">
+      <description>General PWM Timer</description>
+      <originalPack>Renesas.RZN.2.0.0.pack</originalPack>
+    </component>
   </raComponentSelection>
   <raElcConfiguration/>
   <raIcuConfiguration/>
@@ -851,6 +859,118 @@
       <property id="module.driver.ether_selector.duplex" value="module.driver.ether_selector.duplex.full"/>
       <property id="module.driver.ether_selector.ref_clock" value="module.driver.ether_selector.ref_clock.input"/>
     </module>
+    <module id="module.driver.canfd_on_canfd.1443007679">
+      <property id="module.driver.canfd.name" value="g_canfd0"/>
+      <property id="module.driver.canfd.channel" value="0"/>
+      <property id="module.driver.canfd.bitrate.automatic.nominal_rate" value="1000000"/>
+      <property id="module.driver.canfd.bitrate.automatic.data_rate" value="1000000"/>
+      <property id="module.driver.canfd.bitrate.automatic.sample_point" value="75"/>
+      <property id="module.driver.canfd.bitrate.automatic.delay_compensation" value="module.driver.canfd.bitrate.automatic.delay_compensation.enabled"/>
+      <property id="module.driver.canfd.manual.nominal.prescaler" value="1"/>
+      <property id="module.driver.canfd.manual.nominal.time_segment_1" value="29"/>
+      <property id="module.driver.canfd.manual.nominal.time_segment_2" value="10"/>
+      <property id="module.driver.canfd.manual.nominal.sync_jump_width" value="4"/>
+      <property id="module.driver.canfd.manual.data.prescaler" value="1"/>
+      <property id="module.driver.canfd.manual.data.time_segment_1" value="2"/>
+      <property id="module.driver.canfd.manual.data.time_segment_2" value="2"/>
+      <property id="module.driver.canfd.manual.data.sync_jump_width" value="1"/>
+      <property id="module.driver.canfd.bitrate.manual.use_manual" value="module.driver.canfd.bitrate.manual.use_manual.disabled"/>
+      <property id="module.driver.canfd.p_callback" value="canfd0_callback"/>
+      <property id="module.driver.canfd.txmb.int" value="module.driver.canfd.txmb.int.0,module.driver.canfd.txmb.int.1"/>
+      <property id="module.driver.canfd.ch_err.int" value=""/>
+      <property id="module.driver.canfd.ipl" value="board.icu.common.irq.priority12"/>
+      <property id="module.driver.canfd.afl_array" value="p_canfd0_afl"/>
+    </module>
+    <module id="module.driver.canfd_on_canfd.608170521">
+      <property id="module.driver.canfd.name" value="g_canfd1"/>
+      <property id="module.driver.canfd.channel" value="1"/>
+      <property id="module.driver.canfd.bitrate.automatic.nominal_rate" value="1000000"/>
+      <property id="module.driver.canfd.bitrate.automatic.data_rate" value="1000000"/>
+      <property id="module.driver.canfd.bitrate.automatic.sample_point" value="75"/>
+      <property id="module.driver.canfd.bitrate.automatic.delay_compensation" value="module.driver.canfd.bitrate.automatic.delay_compensation.enabled"/>
+      <property id="module.driver.canfd.manual.nominal.prescaler" value="1"/>
+      <property id="module.driver.canfd.manual.nominal.time_segment_1" value="29"/>
+      <property id="module.driver.canfd.manual.nominal.time_segment_2" value="10"/>
+      <property id="module.driver.canfd.manual.nominal.sync_jump_width" value="4"/>
+      <property id="module.driver.canfd.manual.data.prescaler" value="1"/>
+      <property id="module.driver.canfd.manual.data.time_segment_1" value="2"/>
+      <property id="module.driver.canfd.manual.data.time_segment_2" value="2"/>
+      <property id="module.driver.canfd.manual.data.sync_jump_width" value="1"/>
+      <property id="module.driver.canfd.bitrate.manual.use_manual" value="module.driver.canfd.bitrate.manual.use_manual.disabled"/>
+      <property id="module.driver.canfd.p_callback" value="canfd1_callback"/>
+      <property id="module.driver.canfd.txmb.int" value="module.driver.canfd.txmb.int.0,module.driver.canfd.txmb.int.1"/>
+      <property id="module.driver.canfd.ch_err.int" value=""/>
+      <property id="module.driver.canfd.ipl" value="board.icu.common.irq.priority12"/>
+      <property id="module.driver.canfd.afl_array" value="p_canfd1_afl"/>
+    </module>
+    <module id="module.driver.timer_on_gpt.1881673809">
+      <property id="module.driver.timer.name" value="g_timer1"/>
+      <property id="module.driver.gpt.unit" value="1"/>
+      <property id="module.driver.gpt.channel" value="1"/>
+      <property id="module.driver.timer.mode" value="module.driver.timer.mode.mode_periodic"/>
+      <property id="module.driver.timer.period" value="0x100000000"/>
+      <property id="module.driver.timer.unit" value="module.driver.timer.unit.unit_period_raw_counts"/>
+      <property id="module.driver.timer.duty_cycle" value="50"/>
+      <property id="module.driver.timer.gtioca_output_enabled" value="module.driver.timer.gtioca_output_enabled.false"/>
+      <property id="module.driver.timer.gtioca_stop_level" value="module.driver.timer.gtioca_stop_level.pin_level_low"/>
+      <property id="module.driver.timer.gtiocb_output_enabled" value="module.driver.timer.gtiocb_output_enabled.false"/>
+      <property id="module.driver.timer.gtiocb_stop_level" value="module.driver.timer.gtiocb_stop_level.pin_level_low"/>
+      <property id="module.driver.timer.count_up_source" value=""/>
+      <property id="module.driver.timer.count_down_source" value=""/>
+      <property id="module.driver.timer.phase_count_setting_automatically_enable" value="module.driver.timer.phase_count_setting_automatically_enable.disabled"/>
+      <property id="module.driver.timer.counting_mode" value="module.driver.timer.counting_mode.mode1"/>
+      <property id="module.driver.timer.start_source" value=""/>
+      <property id="module.driver.timer.stop_source" value=""/>
+      <property id="module.driver.timer.clear_source" value=""/>
+      <property id="module.driver.timer.capture_a_source" value=""/>
+      <property id="module.driver.timer.capture_b_source" value=""/>
+      <property id="module.driver.timer.gtioca_filter" value="module.driver.timer.gtioc_filter.gtioc_filter_none"/>
+      <property id="module.driver.timer.gtiocb_filter" value="module.driver.timer.gtioc_filter.gtioc_filter_none"/>
+      <property id="module.driver.timer.p_callback" value="timer1_callback"/>
+      <property id="module.driver.timer.ipl" value="board.icu.common.irq.priority12"/>
+      <property id="module.driver.timer.capture_a_ipl" value="_disabled"/>
+      <property id="module.driver.timer.capture_b_ipl" value="_disabled"/>
+      <property id="module.driver.timer.trough_ipl" value="_disabled"/>
+      <property id="module.driver.timer.extra" value="module.driver.timer.extra.disabled"/>
+      <property id="module.driver.timer.poeg_link" value="module.driver.timer.poeg_link.poeg_link_poeg0"/>
+      <property id="module.driver.timer.output_disable" value=""/>
+      <property id="module.driver.timer.adc_trigger" value=""/>
+      <property id="module.driver.timer.dead_time_count_up" value="0"/>
+      <property id="module.driver.timer.dead_time_count_down" value="0"/>
+      <property id="module.driver.timer.adc_a_compare_match" value="0"/>
+      <property id="module.driver.timer.adc_b_compare_match" value="0"/>
+      <property id="module.driver.timer.interrupt_skip.source" value="module.driver.timer.interrupt_skip.source.none"/>
+      <property id="module.driver.timer.interrupt_skip.count" value="module.driver.timer.interrupt_skip.count.count_0"/>
+      <property id="module.driver.timer.interrupt_skip.adc" value="module.driver.timer.interrupt_skip.skip_sources.interrupt_skip.adc.none"/>
+      <property id="module.driver.timer.gtioca_disable_setting" value="module.driver.timer.gtioca_disable_setting.gtioc_disable_prohibited"/>
+      <property id="module.driver.timer.gtiocb_disable_setting" value="module.driver.timer.gtiocb_disable_setting.gtioc_disable_prohibited"/>
+      <property id="module.driver.timer.interrupt_skip_ext1.source" value="module.driver.timer.interrupt_skip_ext1.source.none"/>
+      <property id="module.driver.timer.interrupt_skip_ext1.count" value="module.driver.timer.interrupt_skip_ext1.count.count_0"/>
+      <property id="module.driver.timer.interrupt_skip_ext2.source" value="module.driver.timer.interrupt_skip_ext2.source.none"/>
+      <property id="module.driver.timer.interrupt_skip_ext2.count" value="module.driver.timer.interrupt_skip_ext2.count.count_0"/>
+      <property id="module.driver.timer.interrupt_skip_func.ovf" value="module.driver.timer.interrupt_skip_func.ovf.none"/>
+      <property id="module.driver.timer.interrupt_skip_func.unf" value="module.driver.timer.interrupt_skip_func.unf.none"/>
+      <property id="module.driver.timer.interrupt_skip_func.adc_a" value="module.driver.timer.interrupt_skip_func.adc_a.none"/>
+      <property id="module.driver.timer.interrupt_skip_func.adc_b" value="module.driver.timer.interrupt_skip_func.adc_b.none"/>
+      <property id="module.driver.timer.dead_time_error_ipl" value="_disabled"/>
+      <property id="module.driver.timer.input_capture" value="module.driver.timer.input_capture.enabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_a" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_b" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_c" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_d" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_e" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_f" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_g" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_llpp_event_h" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_a" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_b" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_c" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_d" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_e" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_f" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_g" value="_disabled"/>
+      <property id="module.driver.timer.elc_trigger_nonsafty_event_h" value="_disabled"/>
+    </module>
     <context id="_hal.0">
       <stack module="module.driver.ioport_on_ioport.0"/>
       <stack module="module.bsp.memory_config.0"/>
@@ -864,6 +984,9 @@
         </stack>
         <stack module="module.driver.timer_on_cmt.1877869082" requires="module.middleware.ethercat_ssc_port.requires.timer"/>
       </stack>
+      <stack module="module.driver.canfd_on_canfd.1443007679"/>
+      <stack module="module.driver.canfd_on_canfd.608170521"/>
+      <stack module="module.driver.timer_on_gpt.1881673809"/>
     </context>
     <config id="config.driver.ether_selector">
       <property id="config.driver.ether_selector.param_checking_enable" value="config.driver.ether_selector.param_checking_enable.bsp"/>
@@ -896,9 +1019,72 @@
       <property id="config.driver.cmt.param_checking_enable" value="config.driver.cmt.param_checking_enable.bsp"/>
       <property id="config.driver.cmt.multiplex_interrupt" value="config.driver.cmt.multiplex_interrupt.disabled"/>
     </config>
+    <config id="config.driver.canfd">
+      <property id="config.driver.canfd.param_checking_enable" value="config.driver.canfd.param_checking_enable.bsp"/>
+      <property id="config.driver.canfd.multiplex_interrupt" value="config.driver.canfd.multiplex_interrupt.disabled"/>
+      <property id="config.driver.canfd.global_err.ipl" value="board.icu.common.irq.priority12"/>
+      <property id="config.driver.canfd.global_err.sources" value=""/>
+      <property id="config.driver.canfd.global_err.cb_channel" value="config.driver.canfd.global_err.cb_channel.1"/>
+      <property id="config.driver.canfd.tx_priority" value="config.driver.canfd.tx_priority.buffer"/>
+      <property id="config.driver.canfd.dlc_check" value="config.driver.canfd.dlc_check.disabled"/>
+      <property id="config.driver.canfd.clock_source" value="config.driver.canfd.clock_source.pclkcan"/>
+      <property id="config.driver.canfd.fd.protocol_exception" value="config.driver.canfd.fd.protocol_exception.iso"/>
+      <property id="config.driver.canfd.fd.overflow" value="config.driver.canfd.fd.overflow.reject"/>
+      <property id="config.driver.canfd.rxmb.number" value="0"/>
+      <property id="config.driver.canfd.rxmb.size" value="config.driver.canfd.rxmb.size.8"/>
+      <property id="config.driver.canfd.rxfifo.ipl" value="board.icu.common.irq.priority12"/>
+      <property id="config.driver.canfd.rxfifo.0.enable" value="config.driver.canfd.rxfifo.0.enable.enabled"/>
+      <property id="config.driver.canfd.rxfifo.0.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.0.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.0.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.0.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.rxfifo.1.enable" value="config.driver.canfd.rxfifo.1.enable.enabled"/>
+      <property id="config.driver.canfd.rxfifo.1.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.1.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.1.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.1.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.rxfifo.2.enable" value="config.driver.canfd.rxfifo.2.enable.disabled"/>
+      <property id="config.driver.canfd.rxfifo.2.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.2.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.2.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.2.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.rxfifo.3.enable" value="config.driver.canfd.rxfifo.3.enable.disabled"/>
+      <property id="config.driver.canfd.rxfifo.3.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.3.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.3.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.3.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.rxfifo.4.enable" value="config.driver.canfd.rxfifo.4.enable.disabled"/>
+      <property id="config.driver.canfd.rxfifo.4.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.4.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.4.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.4.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.rxfifo.5.enable" value="config.driver.canfd.rxfifo.5.enable.disabled"/>
+      <property id="config.driver.canfd.rxfifo.5.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.5.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.5.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.5.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.rxfifo.6.enable" value="config.driver.canfd.rxfifo.6.enable.disabled"/>
+      <property id="config.driver.canfd.rxfifo.6.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.6.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.6.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.6.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.rxfifo.7.enable" value="config.driver.canfd.rxfifo.7.enable.disabled"/>
+      <property id="config.driver.canfd.rxfifo.7.int_mode" value="enum.driver.canfd.fifo.int_mode.every_frame"/>
+      <property id="config.driver.canfd.rxfifo.7.int_threshold" value="enum.driver.canfd.fifo.int_threshold.1_2"/>
+      <property id="config.driver.canfd.rxfifo.7.payload" value="enum.driver.canfd.fifo.payload.64"/>
+      <property id="config.driver.canfd.rxfifo.7.depth" value="enum.driver.canfd.fifo.depth.16"/>
+      <property id="config.driver.canfd.afl.ch0_num" value="64"/>
+      <property id="config.driver.canfd.afl.ch1_num" value="64"/>
+    </config>
     <config id="config.driver.ioport">
       <property id="config.driver.ioport.checking" value="config.driver.ioport.checking.system"/>
     </config>
+    <config id="config.driver.gpt">
+      <property id="config.driver.gpt.param_checking_enable" value="config.driver.gpt.param_checking_enable.bsp"/>
+      <property id="config.driver.gpt.output_support_enable" value="config.driver.gpt.output_support_enable.disabled"/>
+      <property id="config.driver.gpt.write_protect_enable" value="config.driver.gpt.write_protect_enable.disabled"/>
+      <property id="config.driver.gpt.multiplex_interrupt" value="config.driver.gpt.multiplex_interrupt.disabled"/>
+    </config>
   </raModuleConfiguration>
   <raPinConfiguration>
     <symbolicName propertyId="p00_0.symbolic_name" value="ETH2_RXD3"/>
@@ -1003,9 +1189,12 @@
     <symbolicName propertyId="p24_1.symbolic_name" value="ETH2_RXCLK"/>
     <symbolicName propertyId="p24_2.symbolic_name" value="ETH2_RXD2"/>
     <pincfg active="true" name="RSK+RZN2L" selected="true" symbol="g_bsp_pin_cfg">
-      <configSetting altId="canfd0.canrx0.p01_7" configurationId="canfd0.canrx0"/>
-      <configSetting altId="canfd0.cantx0.p02_2" configurationId="canfd0.cantx0"/>
+      <configSetting altId="canfd0.canrx0.p05_2" configurationId="canfd0.canrx0"/>
+      <configSetting altId="canfd0.cantx0.p05_3" configurationId="canfd0.cantx0"/>
       <configSetting altId="canfd0.mode.enabled.free" configurationId="canfd0.mode"/>
+      <configSetting altId="canfd1.canrx1.p02_3" configurationId="canfd1.canrx1"/>
+      <configSetting altId="canfd1.cantx1.p02_0" configurationId="canfd1.cantx1"/>
+      <configSetting altId="canfd1.mode.enabled.free" configurationId="canfd1.mode"/>
       <configSetting altId="ether_esc.esc_i2cclk.p13_2" configurationId="ether_esc.esc_i2cclk"/>
       <configSetting altId="ether_esc.esc_i2cdata.p13_3" configurationId="ether_esc.esc_i2cdata"/>
       <configSetting altId="ether_esc.esc_lederr.p20_3" configurationId="ether_esc.esc_lederr"/>
@@ -1060,9 +1249,9 @@
       <configSetting altId="ether_gmac.gmac_mdc.p08_7" configurationId="ether_gmac.gmac_mdc"/>
       <configSetting altId="ether_gmac.gmac_mdio.p09_0" configurationId="ether_gmac.gmac_mdio"/>
       <configSetting altId="ether_gmac.mode.custom_40_1.8v_41.free" configurationId="ether_gmac.mode"/>
-      <configSetting altId="iic1.iic_scl1.p05_2" configurationId="iic1.iic_scl1"/>
-      <configSetting altId="iic1.iic_sda1.p05_3" configurationId="iic1.iic_sda1"/>
-      <configSetting altId="iic1.mode.enabled.free" configurationId="iic1.mode"/>
+      <configSetting altId="gpt0.gtioc0a.p17_4" configurationId="gpt0.gtioc0a"/>
+      <configSetting altId="gpt0.gtioc0b.p00_5" configurationId="gpt0.gtioc0b"/>
+      <configSetting altId="gpt0.mode.custom.free" configurationId="gpt0.mode"/>
       <configSetting altId="jtag_fslash_swd.mode.jtag.free" configurationId="jtag_fslash_swd.mode"/>
       <configSetting altId="jtag_fslash_swd.tck_swclk.p02_7" configurationId="jtag_fslash_swd.tck_swclk"/>
       <configSetting altId="jtag_fslash_swd.tdi.p02_5" configurationId="jtag_fslash_swd.tdi"/>
@@ -1076,6 +1265,9 @@
       <configSetting altId="p00_2.gpio_mode.gpio_mode_peripheral" configurationId="p00_2.gpio_mode"/>
       <configSetting altId="p00_3.ether_eth2.eth2_refclk" configurationId="p00_3"/>
       <configSetting altId="p00_3.gpio_mode.gpio_mode_peripheral" configurationId="p00_3.gpio_mode"/>
+      <configSetting altId="p00_5.gpt0.gtioc0b" configurationId="p00_5"/>
+      <configSetting altId="p00_5.gpio_speed.gpio_speed_middle" configurationId="p00_5.gpio_drivecapacity"/>
+      <configSetting altId="p00_5.gpio_mode.gpio_mode_peripheral" configurationId="p00_5.gpio_mode"/>
       <configSetting altId="p00_6.ether_eth2.eth2_txclk_txc" configurationId="p00_6"/>
       <configSetting altId="p00_6.gpio_speed.gpio_speed_high" configurationId="p00_6.gpio_drivecapacity"/>
       <configSetting altId="p00_6.gpio_mode.gpio_mode_peripheral" configurationId="p00_6.gpio_mode"/>
@@ -1096,12 +1288,12 @@
       <configSetting altId="p01_5.gpio_speed.gpio_speed_high" configurationId="p01_5.gpio_drivecapacity"/>
       <configSetting altId="p01_5.gpio_mode.gpio_mode_peripheral" configurationId="p01_5.gpio_mode"/>
       <configSetting altId="p01_5.sr.sr.fast" configurationId="p01_5.sr"/>
-      <configSetting altId="p01_7.canfd0.canrx0" configurationId="p01_7"/>
-      <configSetting altId="p01_7.gpio_speed.gpio_speed_middle" configurationId="p01_7.gpio_drivecapacity"/>
-      <configSetting altId="p01_7.gpio_mode.gpio_mode_peripheral" configurationId="p01_7.gpio_mode"/>
-      <configSetting altId="p02_2.canfd0.cantx0" configurationId="p02_2"/>
-      <configSetting altId="p02_2.gpio_speed.gpio_speed_middle" configurationId="p02_2.gpio_drivecapacity"/>
-      <configSetting altId="p02_2.gpio_mode.gpio_mode_peripheral" configurationId="p02_2.gpio_mode"/>
+      <configSetting altId="p02_0.canfd1.cantx1" configurationId="p02_0"/>
+      <configSetting altId="p02_0.gpio_speed.gpio_speed_middle" configurationId="p02_0.gpio_drivecapacity"/>
+      <configSetting altId="p02_0.gpio_mode.gpio_mode_peripheral" configurationId="p02_0.gpio_mode"/>
+      <configSetting altId="p02_3.canfd1.canrx1" configurationId="p02_3"/>
+      <configSetting altId="p02_3.gpio_speed.gpio_speed_middle" configurationId="p02_3.gpio_drivecapacity"/>
+      <configSetting altId="p02_3.gpio_mode.gpio_mode_peripheral" configurationId="p02_3.gpio_mode"/>
       <configSetting altId="p02_4.jtag_fslash_swd.tdo" configurationId="p02_4"/>
       <configSetting altId="p02_4.gpio_speed.gpio_speed_high" configurationId="p02_4.gpio_drivecapacity"/>
       <configSetting altId="p02_4.gpio_mode.gpio_mode_peripheral" configurationId="p02_4.gpio_mode"/>
@@ -1122,10 +1314,10 @@
       <configSetting altId="p04_4.gpio_mode.gpio_mode_out.low" configurationId="p04_4.gpio_mode"/>
       <configSetting altId="p05_0.output.low" configurationId="p05_0"/>
       <configSetting altId="p05_0.gpio_mode.gpio_mode_out.low" configurationId="p05_0.gpio_mode"/>
-      <configSetting altId="p05_2.iic1.iic_scl1" configurationId="p05_2"/>
+      <configSetting altId="p05_2.canfd0.canrx0" configurationId="p05_2"/>
       <configSetting altId="p05_2.gpio_speed.gpio_speed_middle" configurationId="p05_2.gpio_drivecapacity"/>
       <configSetting altId="p05_2.gpio_mode.gpio_mode_peripheral" configurationId="p05_2.gpio_mode"/>
-      <configSetting altId="p05_3.iic1.iic_sda1" configurationId="p05_3"/>
+      <configSetting altId="p05_3.canfd0.cantx0" configurationId="p05_3"/>
       <configSetting altId="p05_3.gpio_speed.gpio_speed_middle" configurationId="p05_3.gpio_drivecapacity"/>
       <configSetting altId="p05_3.gpio_mode.gpio_mode_peripheral" configurationId="p05_3.gpio_mode"/>
       <configSetting altId="p05_4.input" configurationId="p05_4"/>
@@ -1298,6 +1490,8 @@
       <configSetting altId="p16_6.sr.sr.fast" configurationId="p16_6.sr"/>
       <configSetting altId="p17_3.output.low" configurationId="p17_3"/>
       <configSetting altId="p17_3.gpio_mode.gpio_mode_out.low" configurationId="p17_3.gpio_mode"/>
+      <configSetting altId="p17_4.gpt0.gtioc0a" configurationId="p17_4"/>
+      <configSetting altId="p17_4.gpio_mode.gpio_mode_peripheral" configurationId="p17_4.gpio_mode"/>
       <configSetting altId="p17_5.usb_hs.usb_ovrcur" configurationId="p17_5"/>
       <configSetting altId="p17_5.gpio_mode.gpio_mode_peripheral" configurationId="p17_5.gpio_mode"/>
       <configSetting altId="p17_7.sci3.rxd_miso3" configurationId="p17_7"/>

+ 38 - 0
projects/etherkit_ethercat_coe/memory_regions.icf

@@ -0,0 +1,38 @@
+
+            /* generated memory regions file - do not edit */
+                            define symbol ATCM_START = 0x00000000;
+                define symbol ATCM_LENGTH   = 0x20000;
+                define symbol BTCM_START = 0x00100000;
+                define symbol BTCM_LENGTH   = 0x20000;
+                define symbol SYSTEM_RAM_START = 0x10000000;
+                define symbol SYSTEM_RAM_LENGTH   = 0x180000;
+                define symbol SYSTEM_RAM_MIRROR_START = 0x30000000;
+                define symbol SYSTEM_RAM_MIRROR_LENGTH   = 0x180000;
+                define symbol xSPI0_CS0_SPACE_MIRROR_START = 0x40000000;
+                define symbol xSPI0_CS0_SPACE_MIRROR_LENGTH   = 0x4000000;
+                define symbol xSPI0_CS1_SPACE_MIRROR_START = 0x44000000;
+                define symbol xSPI0_CS1_SPACE_MIRROR_LENGTH   = 0x4000000;
+                define symbol xSPI1_CS0_SPACE_MIRROR_START = 0x48000000;
+                define symbol xSPI1_CS0_SPACE_MIRROR_LENGTH   = 0x4000000;
+                define symbol CS0_SPACE_MIRROR_START = 0x50000000;
+                define symbol CS0_SPACE_MIRROR_LENGTH   = 0x4000000;
+                define symbol CS2_SPACE_MIRROR_START = 0x54000000;
+                define symbol CS2_SPACE_MIRROR_LENGTH   = 0x4000000;
+                define symbol CS3_SPACE_MIRROR_START = 0x58000000;
+                define symbol CS3_SPACE_MIRROR_LENGTH   = 0x4000000;
+                define symbol CS5_SPACE_MIRROR_START = 0x5C000000;
+                define symbol CS5_SPACE_MIRROR_LENGTH   = 0x4000000;
+                define symbol xSPI0_CS0_SPACE_START = 0x60000000;
+                define symbol xSPI0_CS0_SPACE_LENGTH   = 0x4000000;
+                define symbol xSPI0_CS1_SPACE_START = 0x64000000;
+                define symbol xSPI0_CS1_SPACE_LENGTH   = 0x4000000;
+                define symbol xSPI1_CS0_SPACE_START = 0x68000000;
+                define symbol xSPI1_CS0_SPACE_LENGTH   = 0x4000000;
+                define symbol CS0_SPACE_START = 0x70000000;
+                define symbol CS0_SPACE_LENGTH   = 0x4000000;
+                define symbol CS2_SPACE_START = 0x74000000;
+                define symbol CS2_SPACE_LENGTH   = 0x4000000;
+                define symbol CS3_SPACE_START = 0x78000000;
+                define symbol CS3_SPACE_LENGTH   = 0x4000000;
+                define symbol CS5_SPACE_START = 0x7C000000;
+                define symbol CS5_SPACE_LENGTH   = 0x4000000;

+ 260 - 0
projects/etherkit_ethercat_coe/rzn/fsp/inc/api/r_can_api.h

@@ -0,0 +1,260 @@
+/***********************************************************************************************************************
+ * Copyright [2020-2024] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
+ *
+ * This software and documentation are supplied by Renesas Electronics Corporation and/or its affiliates and may only
+ * be used with products of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.
+ * Renesas products are sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for
+ * the selection and use of Renesas products and Renesas assumes no liability.  No license, express or implied, to any
+ * intellectual property right is granted by Renesas.  This software is protected under all applicable laws, including
+ * copyright laws. Renesas reserves the right to change or discontinue this software and/or this documentation.
+ * THE SOFTWARE AND DOCUMENTATION IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND
+ * TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY,
+ * INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE
+ * SOFTWARE OR DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR
+ * DOCUMENTATION (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER,
+ * INCLUDING, WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY
+ * LOST PROFITS, OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
+ **********************************************************************************************************************/
+
+#ifndef R_CAN_API_H
+#define R_CAN_API_H
+
+/*******************************************************************************************************************//**
+ * @ingroup RENESAS_CONNECTIVITY_INTERFACES
+ * @defgroup CAN_API CAN Interface
+ * @brief Interface for CAN peripheral
+ *
+ * @section CAN_INTERFACE_SUMMARY Summary
+ * The CAN interface provides common APIs for CAN HAL drivers. CAN interface supports following features.
+ * - Full-duplex CAN communication
+ * - Generic CAN parameter setting
+ * - Interrupt driven transmit/receive processing
+ * - Callback function support with returning event code
+ * - Hardware resource locking during a transaction
+ *
+ * @{
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+
+/* Includes board and MCU related header files. */
+#include "bsp_api.h"
+
+/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
+FSP_HEADER
+
+/**********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+
+#if BSP_FEATURE_CANFD_NUM_CHANNELS
+ #define CAN_DATA_BUFFER_LENGTH    (64)
+#else
+ #define CAN_DATA_BUFFER_LENGTH    (8)
+#endif
+
+/**********************************************************************************************************************
+ * Typedef definitions
+ **********************************************************************************************************************/
+
+/** CAN event codes */
+typedef enum e_can_event
+{
+    CAN_EVENT_ERR_WARNING          = 0x0002, ///< Error Warning event.
+    CAN_EVENT_ERR_PASSIVE          = 0x0004, ///< Error Passive event.
+    CAN_EVENT_ERR_BUS_OFF          = 0x0008, ///< Bus Off event.
+    CAN_EVENT_BUS_RECOVERY         = 0x0010, ///< Bus Off Recovery event.
+    CAN_EVENT_MAILBOX_MESSAGE_LOST = 0x0020, ///< Mailbox has been overrun.
+    CAN_EVENT_ERR_BUS_LOCK         = 0x0080, ///< Bus lock detected (32 consecutive dominant bits).
+    CAN_EVENT_ERR_CHANNEL          = 0x0100, ///< Channel error has occurred.
+    CAN_EVENT_TX_ABORTED           = 0x0200, ///< Transmit abort event.
+    CAN_EVENT_RX_COMPLETE          = 0x0400, ///< Receive complete event.
+    CAN_EVENT_TX_COMPLETE          = 0x0800, ///< Transmit complete event.
+    CAN_EVENT_ERR_GLOBAL           = 0x1000, ///< Global error has occurred.
+    CAN_EVENT_TX_FIFO_EMPTY        = 0x2000, ///< Transmit FIFO is empty.
+    CAN_EVENT_FIFO_MESSAGE_LOST    = 0x4000, ///< Receive FIFO overrun.
+} can_event_t;
+
+/** CAN Operation modes */
+typedef enum e_can_operation_mode
+{
+    CAN_OPERATION_MODE_NORMAL = 0,              ///< CAN Normal Operation Mode
+    CAN_OPERATION_MODE_RESET,                   ///< CAN Reset Operation Mode
+    CAN_OPERATION_MODE_HALT,                    ///< CAN Halt Operation Mode
+    CAN_OPERATION_MODE_SLEEP            = 5,    ///< CAN Sleep Operation Mode
+    CAN_OPERATION_MODE_GLOBAL_OPERATION = 0x80, // CANFD Global Operation Mode
+    CAN_OPERATION_MODE_GLOBAL_RESET,            // CANFD Global Reset Mode
+    CAN_OPERATION_MODE_GLOBAL_HALT,             // CANFD Global Halt Mode
+    CAN_OPERATION_MODE_GLOBAL_SLEEP = 0x85      // CANFD Global Sleep Mode
+} can_operation_mode_t;
+
+/** CAN Test modes */
+typedef enum e_can_test_mode
+{
+    CAN_TEST_MODE_DISABLED          = 0,   ///< CAN Test Mode Disabled.
+    CAN_TEST_MODE_LISTEN            = 3,   ///< CAN Test Listen Mode.
+    CAN_TEST_MODE_LOOPBACK_EXTERNAL = 5,   ///< CAN Test External Loopback Mode.
+    CAN_TEST_MODE_LOOPBACK_INTERNAL = 7,   ///< CAN Test Internal Loopback Mode.
+    CAN_TEST_MODE_INTERNAL_BUS      = 0x80 ///< CANFD Internal CAN Bus Communication Test Mode.
+} can_test_mode_t;
+
+/** CAN status info */
+typedef struct st_can_info
+{
+    uint32_t status;                   ///< Useful information from the CAN status register.
+    uint32_t rx_mb_status;             ///< RX Message Buffer New Data flags.
+    uint32_t rx_fifo_status;           ///< RX FIFO Empty flags.
+    uint8_t  error_count_transmit;     ///< Transmit error count.
+    uint8_t  error_count_receive;      ///< Receive error count.
+    uint32_t error_code;               ///< Error code, cleared after reading.
+} can_info_t;
+
+/** CAN ID modes */
+typedef enum e_can_id_mode
+{
+    CAN_ID_MODE_STANDARD,              ///< Standard IDs of 11 bits used.
+    CAN_ID_MODE_EXTENDED,              ///< Extended IDs of 29 bits used.
+} can_id_mode_t;
+
+/** CAN frame types */
+typedef enum e_can_frame_type
+{
+    CAN_FRAME_TYPE_DATA,               ///< Data frame.
+    CAN_FRAME_TYPE_REMOTE,             ///< Remote frame.
+} can_frame_type_t;
+
+/** CAN bit rate configuration. */
+typedef struct st_can_bit_timing_cfg
+{
+    uint32_t baud_rate_prescaler;        ///< Baud rate prescaler. Valid values: 1 - 1024.
+    uint32_t time_segment_1;             ///< Time segment 1 control.
+    uint32_t time_segment_2;             ///< Time segment 2 control.
+    uint32_t synchronization_jump_width; ///< Synchronization jump width.
+} can_bit_timing_cfg_t;
+
+/** CAN data Frame */
+typedef struct st_can_frame
+{
+    uint32_t         id;                           ///< CAN ID.
+    can_id_mode_t    id_mode;                      ///< Standard or Extended ID (IDE).
+    can_frame_type_t type;                         ///< Frame type (RTR).
+    uint8_t          data_length_code;             ///< CAN Data Length Code (DLC).
+    uint32_t         options;                      ///< Implementation-specific options.
+    uint8_t          data[CAN_DATA_BUFFER_LENGTH]; ///< CAN data.
+} can_frame_t;
+
+/** CAN callback parameter definition */
+typedef struct st_can_callback_args
+{
+    uint32_t    channel;               ///< Device channel number.
+    can_event_t event;                 ///< Event code.
+    uint32_t    error;                 ///< Error code.
+    union
+    {
+        uint32_t mailbox;              ///< Mailbox number of interrupt source.
+        uint32_t buffer;               ///< Buffer number of interrupt source.
+    };
+    void const * p_context;            ///< Context provided to user during callback.
+    can_frame_t  frame;                ///< Received frame data.
+} can_callback_args_t;
+
+/** CAN Configuration */
+typedef struct st_can_cfg
+{
+    /* CAN generic configuration */
+    uint32_t               channel;                    ///< CAN channel.
+    can_bit_timing_cfg_t * p_bit_timing;               ///< CAN bit timing.
+
+    /* Configuration for CAN Event processing */
+    void (* p_callback)(can_callback_args_t * p_args); ///< Pointer to callback function
+    void const * p_context;                            ///< User defined callback context.
+
+    /* Pointer to CAN peripheral specific configuration */
+    void const * p_extend;                             ///< CAN hardware dependent configuration
+    uint8_t      ipl;                                  ///< Error/Transmit/Receive interrupt priority
+    IRQn_Type    error_irq;                            ///< Error IRQ number
+    IRQn_Type    rx_irq;                               ///< Receive IRQ number
+    IRQn_Type    tx_irq;                               ///< Transmit IRQ number
+} can_cfg_t;
+
+/** CAN control block.  Allocate an instance specific control block to pass into the CAN API calls.
+ */
+typedef void can_ctrl_t;
+
+/** Shared Interface definition for CAN */
+typedef struct st_can_api
+{
+    /** Open function for CAN device
+     *
+     * @param[in,out]  p_ctrl     Pointer to the CAN control block. Must be declared by user. Value set here.
+     * @param[in]      p_cfg      Pointer to CAN configuration structure. All elements of this structure must be set by
+     *                            user.
+     */
+    fsp_err_t (* open)(can_ctrl_t * const p_ctrl, can_cfg_t const * const p_cfg);
+
+    /** Write function for CAN device
+     * @param[in]   p_ctrl          Pointer to the CAN control block.
+     * @param[in]   buffer          Buffer number (mailbox or message buffer) to write to.
+     * @param[in]   p_frame         Pointer for frame of CAN ID, DLC, data and frame type to write.
+     */
+    fsp_err_t (* write)(can_ctrl_t * const p_ctrl, uint32_t buffer_number, can_frame_t * const p_frame);
+
+    /** Read function for CAN device
+     * @param[in]   p_ctrl          Pointer to the CAN control block.
+     * @param[in]   buffer          Message buffer (number) to read from.
+     * @param[in]   p_frame         Pointer to store the CAN ID, DLC, data and frame type.
+     */
+    fsp_err_t (* read)(can_ctrl_t * const p_ctrl, uint32_t buffer_number, can_frame_t * const p_frame);
+
+    /** Close function for CAN device
+     * @param[in]   p_ctrl     Pointer to the CAN control block.
+     */
+    fsp_err_t (* close)(can_ctrl_t * const p_ctrl);
+
+    /** Mode Transition function for CAN device
+     * @param[in]   p_ctrl               Pointer to the CAN control block.
+     * @param[in]   operation_mode       Destination CAN operation state.
+     * @param[in]   test_mode            Destination CAN test state.
+     */
+    fsp_err_t (* modeTransition)(can_ctrl_t * const p_ctrl, can_operation_mode_t operation_mode,
+                                 can_test_mode_t test_mode);
+
+    /** Get CAN channel info.
+     *
+     * @param[in]   p_ctrl  Handle for channel (pointer to channel control block)
+     * @param[out]  p_info  Memory address to return channel specific data to.
+     */
+    fsp_err_t (* infoGet)(can_ctrl_t * const p_ctrl, can_info_t * const p_info);
+
+    /** Specify callback function and optional context pointer and working memory pointer.
+     *
+     * @param[in]   p_ctrl                   Control block set in @ref can_api_t::open call.
+     * @param[in]   p_callback               Callback function to register
+     * @param[in]   p_context                Pointer to send to callback function
+     * @param[in]   p_working_memory         Pointer to volatile memory where callback structure can be allocated.
+     *                                       Callback arguments allocated here are only valid during the callback.
+     */
+    fsp_err_t (* callbackSet)(can_ctrl_t * const p_ctrl, void (* p_callback)(can_callback_args_t *),
+                              void const * const p_context, can_callback_args_t * const p_callback_memory);
+} can_api_t;
+
+/** This structure encompasses everything that is needed to use an instance of this interface. */
+typedef struct st_can_instance
+{
+    can_ctrl_t      * p_ctrl;          ///< Pointer to the control structure for this instance
+    can_cfg_t const * p_cfg;           ///< Pointer to the configuration structure for this instance
+    can_api_t const * p_api;           ///< Pointer to the API structure for this instance
+} can_instance_t;
+
+/*******************************************************************************************************************//**
+ * @} (end defgroup CAN_API)
+ **********************************************************************************************************************/
+
+/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
+FSP_FOOTER
+
+#endif

+ 368 - 0
projects/etherkit_ethercat_coe/rzn/fsp/inc/instances/r_canfd.h

@@ -0,0 +1,368 @@
+/***********************************************************************************************************************
+ * Copyright [2020-2024] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
+ *
+ * This software and documentation are supplied by Renesas Electronics Corporation and/or its affiliates and may only
+ * be used with products of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.
+ * Renesas products are sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for
+ * the selection and use of Renesas products and Renesas assumes no liability.  No license, express or implied, to any
+ * intellectual property right is granted by Renesas.  This software is protected under all applicable laws, including
+ * copyright laws. Renesas reserves the right to change or discontinue this software and/or this documentation.
+ * THE SOFTWARE AND DOCUMENTATION IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND
+ * TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY,
+ * INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE
+ * SOFTWARE OR DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR
+ * DOCUMENTATION (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER,
+ * INCLUDING, WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY
+ * LOST PROFITS, OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
+ **********************************************************************************************************************/
+
+#ifndef R_CANFD_H
+#define R_CANFD_H
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+#include "bsp_api.h"
+#include "r_canfd_cfg.h"
+#include "r_can_api.h"
+
+/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
+FSP_HEADER
+
+/*******************************************************************************************************************//**
+ * @addtogroup CANFD
+ * @{
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+
+/**********************************************************************************************************************
+ * Typedef definitions
+ **********************************************************************************************************************/
+
+/** CANFD Status */
+typedef enum e_canfd_status
+{
+    CANFD_STATUS_RESET_MODE    = 0x001, ///< Channel in Reset mode
+    CANFD_STATUS_HALT_MODE     = 0x002, ///< Channel in Halt mode
+    CANFD_STATUS_SLEEP_MODE    = 0x004, ///< Channel in Sleep mode
+    CANFD_STATUS_ERROR_PASSIVE = 0x008, ///< Channel in error-passive state
+    CANFD_STATUS_BUS_OFF       = 0x010, ///< Channel in bus-off state
+    CANFD_STATUS_TRANSMITTING  = 0x020, ///< Channel is transmitting
+    CANFD_STATUS_RECEIVING     = 0x040, ///< Channel is receiving
+    CANFD_STATUS_READY         = 0x080, ///< Channel is ready for communication
+    CANFD_STATUS_ESI           = 0x100, ///< At least one CAN-FD message was received with the ESI flag set
+} canfd_status_t;
+
+/** CANFD Error Code */
+typedef enum e_canfd_error
+{
+    CANFD_ERROR_CHANNEL_BUS              = 0x00000001, ///< Bus Error
+    CANFD_ERROR_CHANNEL_WARNING          = 0x00000002, ///< Error Warning (TX/RX error count over 0x5F)
+    CANFD_ERROR_CHANNEL_PASSIVE          = 0x00000004, ///< Error Passive (TX/RX error count over 0x7F)
+    CANFD_ERROR_CHANNEL_BUS_OFF_ENTRY    = 0x00000008, ///< Bus-Off State Entry
+    CANFD_ERROR_CHANNEL_BUS_OFF_RECOVERY = 0x00000010, ///< Recovery from Bus-Off State
+    CANFD_ERROR_CHANNEL_OVERLOAD         = 0x00000020, ///< Overload
+    CANFD_ERROR_CHANNEL_BUS_LOCK         = 0x00000040, ///< Bus Locked
+    CANFD_ERROR_CHANNEL_ARBITRATION_LOSS = 0x00000080, ///< Arbitration Lost
+    CANFD_ERROR_CHANNEL_STUFF            = 0x00000100, ///< Stuff Error
+    CANFD_ERROR_CHANNEL_FORM             = 0x00000200, ///< Form Error
+    CANFD_ERROR_CHANNEL_ACK              = 0x00000400, ///< ACK Error
+    CANFD_ERROR_CHANNEL_CRC              = 0x00000800, ///< CRC Error
+    CANFD_ERROR_CHANNEL_BIT_RECESSIVE    = 0x00001000, ///< Bit Error (recessive) Error
+    CANFD_ERROR_CHANNEL_BIT_DOMINANT     = 0x00002000, ///< Bit Error (dominant) Error
+    CANFD_ERROR_CHANNEL_ACK_DELIMITER    = 0x00004000, ///< ACK Delimiter Error
+    CANFD_ERROR_GLOBAL_DLC               = 0x00010000, ///< DLC Error
+    CANFD_ERROR_GLOBAL_MESSAGE_LOST      = 0x00020000, ///< Message Lost
+    CANFD_ERROR_GLOBAL_PAYLOAD_OVERFLOW  = 0x00080000, ///< FD Payload Overflow
+    CANFD_ERROR_GLOBAL_TXQ_OVERWRITE     = 0x00100000, ///< TX Queue Message Overwrite
+    CANFD_ERROR_GLOBAL_TXQ_MESSAGE_LOST  = 0x00400000, ///< TX Queue Message Lost
+    CANFD_ERROR_GLOBAL_CH0_SCAN_FAIL     = 0x01000000, ///< Channel 0 RX Scan Failure
+    CANFD_ERROR_GLOBAL_CH1_SCAN_FAIL     = 0x02000000, ///< Channel 1 RX Scan Failure
+    CANFD_ERROR_GLOBAL_CH0_ECC           = 0x10000000, ///< Channel 0 ECC Error
+    CANFD_ERROR_GLOBAL_CH1_ECC           = 0x20000000, ///< Channel 1 ECC Error
+} canfd_error_t;
+
+/** CANFD Transmit Message Buffer (TX MB) */
+typedef enum e_canfd_tx_mb
+{
+    CANFD_TX_MB_0  = 0,
+    CANFD_TX_MB_1  = 1,
+    CANFD_TX_MB_2  = 2,
+    CANFD_TX_MB_3  = 3,
+    CANFD_TX_MB_4  = 4,
+    CANFD_TX_MB_5  = 5,
+    CANFD_TX_MB_6  = 6,
+    CANFD_TX_MB_7  = 7,
+    CANFD_TX_MB_8  = 8,
+    CANFD_TX_MB_9  = 9,
+    CANFD_TX_MB_10 = 10,
+    CANFD_TX_MB_11 = 11,
+    CANFD_TX_MB_12 = 12,
+    CANFD_TX_MB_13 = 13,
+    CANFD_TX_MB_14 = 14,
+    CANFD_TX_MB_15 = 15,
+    CANFD_TX_MB_32 = 32,
+    CANFD_TX_MB_33 = 33,
+    CANFD_TX_MB_34 = 34,
+    CANFD_TX_MB_35 = 35,
+    CANFD_TX_MB_36 = 36,
+    CANFD_TX_MB_37 = 37,
+    CANFD_TX_MB_38 = 38,
+    CANFD_TX_MB_39 = 39,
+    CANFD_TX_MB_40 = 40,
+    CANFD_TX_MB_41 = 41,
+    CANFD_TX_MB_42 = 42,
+    CANFD_TX_MB_43 = 43,
+    CANFD_TX_MB_44 = 44,
+    CANFD_TX_MB_45 = 45,
+    CANFD_TX_MB_46 = 46,
+    CANFD_TX_MB_47 = 47,
+} canfd_tx_mb_t;
+
+/** CANFD Receive Buffer (MB + FIFO) */
+typedef enum e_canfd_rx_buffer
+{
+    CANFD_RX_BUFFER_MB_0   = 0,
+    CANFD_RX_BUFFER_MB_1   = 1,
+    CANFD_RX_BUFFER_MB_2   = 2,
+    CANFD_RX_BUFFER_MB_3   = 3,
+    CANFD_RX_BUFFER_MB_4   = 4,
+    CANFD_RX_BUFFER_MB_5   = 5,
+    CANFD_RX_BUFFER_MB_6   = 6,
+    CANFD_RX_BUFFER_MB_7   = 7,
+    CANFD_RX_BUFFER_MB_8   = 8,
+    CANFD_RX_BUFFER_MB_9   = 9,
+    CANFD_RX_BUFFER_MB_10  = 10,
+    CANFD_RX_BUFFER_MB_11  = 11,
+    CANFD_RX_BUFFER_MB_12  = 12,
+    CANFD_RX_BUFFER_MB_13  = 13,
+    CANFD_RX_BUFFER_MB_14  = 14,
+    CANFD_RX_BUFFER_MB_15  = 15,
+    CANFD_RX_BUFFER_MB_16  = 16,
+    CANFD_RX_BUFFER_MB_17  = 17,
+    CANFD_RX_BUFFER_MB_18  = 18,
+    CANFD_RX_BUFFER_MB_19  = 19,
+    CANFD_RX_BUFFER_MB_20  = 20,
+    CANFD_RX_BUFFER_MB_21  = 21,
+    CANFD_RX_BUFFER_MB_22  = 22,
+    CANFD_RX_BUFFER_MB_23  = 23,
+    CANFD_RX_BUFFER_MB_24  = 24,
+    CANFD_RX_BUFFER_MB_25  = 25,
+    CANFD_RX_BUFFER_MB_26  = 26,
+    CANFD_RX_BUFFER_MB_27  = 27,
+    CANFD_RX_BUFFER_MB_28  = 28,
+    CANFD_RX_BUFFER_MB_29  = 29,
+    CANFD_RX_BUFFER_MB_30  = 30,
+    CANFD_RX_BUFFER_MB_31  = 31,
+    CANFD_RX_BUFFER_FIFO_0 = 32,
+    CANFD_RX_BUFFER_FIFO_1 = 33,
+    CANFD_RX_BUFFER_FIFO_2 = 34,
+    CANFD_RX_BUFFER_FIFO_3 = 35,
+    CANFD_RX_BUFFER_FIFO_4 = 36,
+    CANFD_RX_BUFFER_FIFO_5 = 37,
+    CANFD_RX_BUFFER_FIFO_6 = 38,
+    CANFD_RX_BUFFER_FIFO_7 = 39,
+} canfd_rx_buffer_t;
+
+/** CANFD Receive Message Buffer (RX MB) */
+typedef enum e_canfd_rx_mb
+{
+    CANFD_RX_MB_NONE = 0,
+    CANFD_RX_MB_0    = 0x80,
+    CANFD_RX_MB_1    = 0x80 + 1,
+    CANFD_RX_MB_2    = 0x80 + 2,
+    CANFD_RX_MB_3    = 0x80 + 3,
+    CANFD_RX_MB_4    = 0x80 + 4,
+    CANFD_RX_MB_5    = 0x80 + 5,
+    CANFD_RX_MB_6    = 0x80 + 6,
+    CANFD_RX_MB_7    = 0x80 + 7,
+    CANFD_RX_MB_8    = 0x80 + 8,
+    CANFD_RX_MB_9    = 0x80 + 9,
+    CANFD_RX_MB_10   = 0x80 + 10,
+    CANFD_RX_MB_11   = 0x80 + 11,
+    CANFD_RX_MB_12   = 0x80 + 12,
+    CANFD_RX_MB_13   = 0x80 + 13,
+    CANFD_RX_MB_14   = 0x80 + 14,
+    CANFD_RX_MB_15   = 0x80 + 15,
+    CANFD_RX_MB_16   = 0x80 + 16,
+    CANFD_RX_MB_17   = 0x80 + 17,
+    CANFD_RX_MB_18   = 0x80 + 18,
+    CANFD_RX_MB_19   = 0x80 + 19,
+    CANFD_RX_MB_20   = 0x80 + 20,
+    CANFD_RX_MB_21   = 0x80 + 21,
+    CANFD_RX_MB_22   = 0x80 + 22,
+    CANFD_RX_MB_23   = 0x80 + 23,
+    CANFD_RX_MB_24   = 0x80 + 24,
+    CANFD_RX_MB_25   = 0x80 + 25,
+    CANFD_RX_MB_26   = 0x80 + 26,
+    CANFD_RX_MB_27   = 0x80 + 27,
+    CANFD_RX_MB_28   = 0x80 + 28,
+    CANFD_RX_MB_29   = 0x80 + 29,
+    CANFD_RX_MB_30   = 0x80 + 30,
+    CANFD_RX_MB_31   = 0x80 + 31,
+} canfd_rx_mb_t;
+
+/** CANFD Receive FIFO (RX FIFO) */
+typedef enum e_canfd_rx_fifo
+{
+    CANFD_RX_FIFO_0 = (1U),
+    CANFD_RX_FIFO_1 = (1U << 1),
+    CANFD_RX_FIFO_2 = (1U << 2),
+    CANFD_RX_FIFO_3 = (1U << 3),
+    CANFD_RX_FIFO_4 = (1U << 4),
+    CANFD_RX_FIFO_5 = (1U << 5),
+    CANFD_RX_FIFO_6 = (1U << 6),
+    CANFD_RX_FIFO_7 = (1U << 7),
+} canfd_rx_fifo_t;
+
+/** CANFD AFL Minimum DLC settings */
+typedef enum e_canfd_minimum_dlc
+{
+    CANFD_MINIMUM_DLC_0 = 0,
+    CANFD_MINIMUM_DLC_1,
+    CANFD_MINIMUM_DLC_2,
+    CANFD_MINIMUM_DLC_3,
+    CANFD_MINIMUM_DLC_4,
+    CANFD_MINIMUM_DLC_5,
+    CANFD_MINIMUM_DLC_6,
+    CANFD_MINIMUM_DLC_7,
+    CANFD_MINIMUM_DLC_8,
+    CANFD_MINIMUM_DLC_12,
+    CANFD_MINIMUM_DLC_16,
+    CANFD_MINIMUM_DLC_20,
+    CANFD_MINIMUM_DLC_24,
+    CANFD_MINIMUM_DLC_32,
+    CANFD_MINIMUM_DLC_48,
+    CANFD_MINIMUM_DLC_64,
+} canfd_minimum_dlc_t;
+
+/** CANFD Frame Options */
+typedef enum e_canfd_frame_option
+{
+    CANFD_FRAME_OPTION_ERROR = 0x01,   ///< Error state set (ESI).
+    CANFD_FRAME_OPTION_BRS   = 0x02,   ///< Bit Rate Switching (BRS) enabled.
+    CANFD_FRAME_OPTION_FD    = 0x04,   ///< Flexible Data frame (FDF).
+    // CANFD_FRAME_OPTION_ONESHOT = 0x80, ///< One-shot mode (no retries).
+} canfd_frame_options_t;
+
+/* CAN Instance Control Block   */
+typedef struct st_canfd_instance_ctrl
+{
+    /* Parameters to control CAN peripheral device */
+    can_cfg_t const    * p_cfg;                 // Pointer to the configuration structure
+    uint32_t             open;                  // Open status of channel.
+    can_operation_mode_t operation_mode;        // Can operation mode.
+    can_test_mode_t      test_mode;             // Can operation mode.
+#if BSP_TZ_SECURE_BUILD
+    bool callback_is_secure;                    // If the callback is in non-secure memory then a security state transistion is required to call p_callback (BLXNS)
+#endif
+    void (* p_callback)(can_callback_args_t *); // Pointer to callback
+    can_callback_args_t * p_callback_memory;    // Pointer to optional callback argument memory
+    void const          * p_context;            // Pointer to context to be passed into callback function
+} canfd_instance_ctrl_t;
+
+/** AFL Entry (based on R_CANFD_CFDGAFL_Type in renesas.h) */
+typedef struct st_canfd_afl_entry_t
+{
+    union
+    {
+        uint32_t id_u32;
+
+        struct
+        {
+            uint32_t id                 : 29; ///< ID to match against
+            uint32_t                    : 1;
+            can_frame_type_t frame_type : 1;  ///< Frame type (Data or Remote)
+            can_id_mode_t    id_mode    : 1;  ///< ID mode (Standard or Extended)
+        } id;
+    };
+
+    union
+    {
+        uint32_t mask_u32;
+
+        struct
+        {
+            uint32_t mask_id         : 29; ///< ID Mask
+            uint32_t                 : 1;
+            uint32_t mask_frame_type : 1;  ///< Only accept frames with the configured frame type
+            uint32_t mask_id_mode    : 1;  ///< Only accept frames with the configured ID mode
+        } mask;
+    };
+
+    union
+    {
+        uint32_t destination_u32[2];
+
+        struct
+        {
+            canfd_minimum_dlc_t minimum_dlc : 4; ///< Minimum DLC value to accept (valid when DLC Check is enabled)
+            uint32_t                        : 4;
+            canfd_rx_mb_t rx_buffer         : 8; ///< RX Message Buffer to receive messages accepted by this rule
+            uint32_t                        : 16;
+            canfd_rx_fifo_t fifo_select_flags;   ///< RX FIFO(s) to receive messages accepted by this rule
+        } destination;
+    };
+} canfd_afl_entry_t;
+
+/** CANFD Global Configuration */
+typedef struct st_canfd_global_cfg
+{
+    uint32_t global_interrupts;        ///< Global control options (CFDGCTR register setting)
+    uint32_t global_config;            ///< Global configuration options (CFDGCFG register setting)
+    uint32_t rx_fifo_config[8];        ///< RX FIFO configuration (CFDRFCCn register settings)
+    uint32_t rx_mb_config;             ///< Number and size of RX Message Buffers (CFDRMNB register setting)
+    uint8_t  global_err_ipl;           ///< Global Error interrupt priority
+    uint8_t  rx_fifo_ipl;              ///< RX FIFO interrupt priority
+} canfd_global_cfg_t;
+
+/** CANFD Extended Configuration */
+typedef struct st_canfd_extended_cfg
+{
+    canfd_afl_entry_t const * p_afl;           ///< AFL rules list
+    uint64_t               txmb_txi_enable;    ///< Array of TX Message Buffer enable bits
+    uint32_t               error_interrupts;   ///< Error interrupt enable bits
+    can_bit_timing_cfg_t * p_data_timing;      ///< FD Data Rate (when bitrate switching is used)
+    uint8_t                delay_compensation; ///< FD Transceiver Delay Compensation (enable or disable)
+    canfd_global_cfg_t   * p_global_cfg;       ///< Global configuration (global error callback channel only)
+} canfd_extended_cfg_t;
+
+/**********************************************************************************************************************
+ * Exported global variables
+ **********************************************************************************************************************/
+
+/** @cond INC_HEADER_DEFS_SEC */
+/** Filled in Interface API structure for this Instance. */
+extern const can_api_t g_canfd_on_canfd;
+
+/** @endcond */
+
+/***********************************************************************************************************************
+ * Public APIs
+ **********************************************************************************************************************/
+fsp_err_t R_CANFD_Open(can_ctrl_t * const p_ctrl, can_cfg_t const * const p_cfg);
+fsp_err_t R_CANFD_Close(can_ctrl_t * const p_ctrl);
+fsp_err_t R_CANFD_Write(can_ctrl_t * const p_ctrl, uint32_t const buffer, can_frame_t * const p_frame);
+fsp_err_t R_CANFD_Read(can_ctrl_t * const p_ctrl, uint32_t const buffer, can_frame_t * const p_frame);
+fsp_err_t R_CANFD_ModeTransition(can_ctrl_t * const   p_ctrl,
+                                 can_operation_mode_t operation_mode,
+                                 can_test_mode_t      test_mode);
+fsp_err_t R_CANFD_InfoGet(can_ctrl_t * const p_ctrl, can_info_t * const p_info);
+fsp_err_t R_CANFD_CallbackSet(can_ctrl_t * const          p_ctrl,
+                              void (                    * p_callback)(can_callback_args_t *),
+                              void const * const          p_context,
+                              can_callback_args_t * const p_callback_memory);
+
+/*******************************************************************************************************************//**
+ * @} (end defgroup CAN)
+ **********************************************************************************************************************/
+
+/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
+FSP_FOOTER
+
+#endif

+ 431 - 0
projects/etherkit_ethercat_coe/rzn/fsp/inc/instances/r_gpt.h

@@ -0,0 +1,431 @@
+/***********************************************************************************************************************
+ * Copyright [2020-2024] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
+ *
+ * This software and documentation are supplied by Renesas Electronics Corporation and/or its affiliates and may only
+ * be used with products of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.
+ * Renesas products are sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for
+ * the selection and use of Renesas products and Renesas assumes no liability.  No license, express or implied, to any
+ * intellectual property right is granted by Renesas.  This software is protected under all applicable laws, including
+ * copyright laws. Renesas reserves the right to change or discontinue this software and/or this documentation.
+ * THE SOFTWARE AND DOCUMENTATION IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND
+ * TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY,
+ * INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE
+ * SOFTWARE OR DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR
+ * DOCUMENTATION (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER,
+ * INCLUDING, WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY
+ * LOST PROFITS, OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
+ **********************************************************************************************************************/
+
+#ifndef R_GPT_H
+#define R_GPT_H
+
+/*******************************************************************************************************************//**
+ * @addtogroup GPT
+ * @{
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+#include "bsp_api.h"
+#include "r_timer_api.h"
+
+/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
+FSP_HEADER
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+
+/* Values to assign to GTUPSR, GTDNSR registers to determine phase counting mode. */
+#define GPT_PHASE_COUNTING_MODE_1_UP      (0x00006900U)
+#define GPT_PHASE_COUNTING_MODE_1_DN      (0x00009600U)
+#define GPT_PHASE_COUNTING_MODE_200_UP    (0x00000800U)
+#define GPT_PHASE_COUNTING_MODE_200_DN    (0x00000400U)
+#define GPT_PHASE_COUNTING_MODE_201_UP    (0x00000200U)
+#define GPT_PHASE_COUNTING_MODE_201_DN    (0x00000100U)
+#define GPT_PHASE_COUNTING_MODE_210_UP    (0x00000A00U)
+#define GPT_PHASE_COUNTING_MODE_210_DN    (0x00000500U)
+#define GPT_PHASE_COUNTING_MODE_300_UP    (0x00000800U)
+#define GPT_PHASE_COUNTING_MODE_300_DN    (0x00008000U)
+#define GPT_PHASE_COUNTING_MODE_301_UP    (0x00000200U)
+#define GPT_PHASE_COUNTING_MODE_301_DN    (0x00002000U)
+#define GPT_PHASE_COUNTING_MODE_310_UP    (0x00000A00U)
+#define GPT_PHASE_COUNTING_MODE_310_DN    (0x0000A000U)
+#define GPT_PHASE_COUNTING_MODE_4_UP      (0x00006000U)
+#define GPT_PHASE_COUNTING_MODE_4_DN      (0x00009000U)
+#define GPT_PHASE_COUNTING_MODE_50_UP     (0x00000C00U)
+#define GPT_PHASE_COUNTING_MODE_50_DN     (0x00000000U)
+#define GPT_PHASE_COUNTING_MODE_51_UP     (0x0000C000U)
+#define GPT_PHASE_COUNTING_MODE_51_DN     (0x00000000U)
+
+/***********************************************************************************************************************
+ * Typedef definitions
+ **********************************************************************************************************************/
+
+/** Input/Output pins, used to select which duty cycle to update in R_GPT_DutyCycleSet(). */
+typedef enum e_gpt_io_pin
+{
+    GPT_IO_PIN_GTIOCA            = 0,  ///< GTIOCA
+    GPT_IO_PIN_GTIOCB            = 1,  ///< GTIOCB
+    GPT_IO_PIN_GTIOCA_AND_GTIOCB = 2,  ///< GTIOCA and GTIOCB
+} gpt_io_pin_t;
+
+/** Level of GPT pin */
+typedef enum e_gpt_pin_level
+{
+    GPT_PIN_LEVEL_LOW  = 0,            ///< Pin level low
+    GPT_PIN_LEVEL_HIGH = 1,            ///< Pin level high
+} gpt_pin_level_t;
+
+typedef enum e_gpt_channel
+{
+    GPT_CHANNEL_UNIT0_0 = 0,           ///< Unit0 channel0
+    GPT_CHANNEL_UNIT0_1 = 1,           ///< Unit0 channel1
+    GPT_CHANNEL_UNIT0_2 = 2,           ///< Unit0 channel2
+    GPT_CHANNEL_UNIT0_3 = 3,           ///< Unit0 channel3
+    GPT_CHANNEL_UNIT0_4 = 4,           ///< Unit0 channel4
+    GPT_CHANNEL_UNIT0_5 = 5,           ///< Unit0 channel5
+    GPT_CHANNEL_UNIT0_6 = 6,           ///< Unit0 channel6
+    GPT_CHANNEL_UNIT1_0 = 7,           ///< Unit1 channel0
+    GPT_CHANNEL_UNIT1_1 = 8,           ///< Unit1 channel1
+    GPT_CHANNEL_UNIT1_2 = 9,           ///< Unit1 channel2
+    GPT_CHANNEL_UNIT1_3 = 10,          ///< Unit1 channel3
+    GPT_CHANNEL_UNIT1_4 = 11,          ///< Unit1 channel4
+    GPT_CHANNEL_UNIT1_5 = 12,          ///< Unit1 channel5
+    GPT_CHANNEL_UNIT1_6 = 13,          ///< Unit1 channel6
+    GPT_CHANNEL_UNIT2_0 = 14,          ///< Unit2 channel0
+    GPT_CHANNEL_UNIT2_1 = 15,          ///< Unit2 channel1
+    GPT_CHANNEL_UNIT2_2 = 16,          ///< Unit2 channel2
+    GPT_CHANNEL_UNIT2_3 = 17,          ///< Unit2 channel3
+} gpt_channel_t;
+
+/** Sources can be used to start the timer, stop the timer, count up, or count down. These enumerations represent
+ * a bitmask. Multiple sources can be ORed together. */
+typedef enum e_gpt_source
+{
+    /** No active event sources. */
+    GPT_SOURCE_NONE = 0U,
+
+    /** Action performed on GTETRGA rising edge. **/
+    GPT_SOURCE_GTETRGA_RISING = (1U << 0),
+
+    /** Action performed on GTETRGA falling edge. **/
+    GPT_SOURCE_GTETRGA_FALLING = (1U << 1),
+
+    /** Action performed on GTETRGB rising edge. **/
+    GPT_SOURCE_GTETRGB_RISING = (1U << 2),
+
+    /** Action performed on GTETRGB falling edge. **/
+    GPT_SOURCE_GTETRGB_FALLING = (1U << 3),
+
+    /** Action performed on GTETRGC rising edge. **/
+    GPT_SOURCE_GTETRGC_RISING = (1U << 4),
+
+    /** Action performed on GTETRGC falling edge. **/
+    GPT_SOURCE_GTETRGC_FALLING = (1U << 5),
+
+    /** Action performed on GTETRGB rising edge. **/
+    GPT_SOURCE_GTETRGD_RISING = (1U << 6),
+
+    /** Action performed on GTETRGB falling edge. **/
+    GPT_SOURCE_GTETRGD_FALLING = (1U << 7),
+
+    /** Action performed when GTIOCA input rises while GTIOCB is low. **/
+    GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW = (1U << 8),
+
+    /** Action performed when GTIOCA input rises while GTIOCB is high. **/
+    GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH = (1U << 9),
+
+    /** Action performed when GTIOCA input falls while GTIOCB is low. **/
+    GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW = (1U << 10),
+
+    /** Action performed when GTIOCA input falls while GTIOCB is high. **/
+    GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH = (1U << 11),
+
+    /** Action performed when GTIOCB input rises while GTIOCA is low. **/
+    GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW = (1U << 12),
+
+    /** Action performed when GTIOCB input rises while GTIOCA is high. **/
+    GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH = (1U << 13),
+
+    /** Action performed when GTIOCB input falls while GTIOCA is low. **/
+    GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW = (1U << 14),
+
+    /** Action performed when GTIOCB input falls while GTIOCA is high. **/
+    GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH = (1U << 15),
+
+    /** Action performed on ELC GPTA event. **/
+    GPT_SOURCE_GPT_A = (1U << 16),
+
+    /** Action performed on ELC GPTB event. **/
+    GPT_SOURCE_GPT_B = (1U << 17),
+
+    /** Action performed on ELC GPTC event. **/
+    GPT_SOURCE_GPT_C = (1U << 18),
+
+    /** Action performed on ELC GPTD event. **/
+    GPT_SOURCE_GPT_D = (1U << 19),
+
+    /** Action performed on ELC GPTE event. **/
+    GPT_SOURCE_GPT_E = (1U << 20),
+
+    /** Action performed on ELC GPTF event. **/
+    GPT_SOURCE_GPT_F = (1U << 21),
+
+    /** Action performed on ELC GPTG event. **/
+    GPT_SOURCE_GPT_G = (1U << 22),
+
+    /** Action performed on ELC GPTH event. **/
+    GPT_SOURCE_GPT_H = (1U << 23),
+} gpt_source_t;
+
+/** Configurations for output pins. */
+typedef struct s_gpt_output_pin
+{
+    bool            output_enabled;    ///< Set to true to enable output, false to disable output
+    gpt_pin_level_t stop_level;        ///< Select a stop level from ::gpt_pin_level_t
+} gpt_output_pin_t;
+
+/** Input capture signal noise filter (debounce) setting. Only available for input signals GTIOCxA and GTIOCxB.
+ *   The noise filter samples the external signal at intervals of the PCLK divided by one of the values.
+ *   When 3 consecutive samples are at the same level (high or low), then that level is passed on as
+ *   the observed state of the signal. See "Noise Filter Function" in the hardware manual, GPT section.
+ */
+typedef enum e_gpt_capture_filter
+{
+    GPT_CAPTURE_FILTER_NONE         = 0U, ///< None - no filtering
+    GPT_CAPTURE_FILTER_PCLKD_DIV_1  = 1U, ///< PCLK/1 - fast sampling
+    GPT_CAPTURE_FILTER_PCLKD_DIV_4  = 3U, ///< PCLK/4
+    GPT_CAPTURE_FILTER_PCLKD_DIV_16 = 5U, ///< PCLK/16
+    GPT_CAPTURE_FILTER_PCLKD_DIV_64 = 7U, ///< PCLK/64 - slow sampling
+} gpt_capture_filter_t;
+
+/** Trigger options to start A/D conversion. */
+typedef enum e_gpt_adc_trigger
+{
+    GPT_ADC_TRIGGER_NONE                   = 0U,      ///< None - no output disable request
+    GPT_ADC_TRIGGER_UP_COUNT_START_ADC_A   = 1U << 0, ///< Request A/D conversion from ADC unit 0 at up counting compare match of @ref gpt_extended_pwm_cfg_t::adc_a_compare_match
+    GPT_ADC_TRIGGER_DOWN_COUNT_START_ADC_A = 1U << 1, ///< Request A/D conversion from ADC unit 0 at down counting compare match of @ref gpt_extended_pwm_cfg_t::adc_a_compare_match
+    GPT_ADC_TRIGGER_UP_COUNT_START_ADC_B   = 1U << 2, ///< Request A/D conversion from ADC unit 1 at up counting compare match of @ref gpt_extended_pwm_cfg_t::adc_b_compare_match
+    GPT_ADC_TRIGGER_DOWN_COUNT_START_ADC_B = 1U << 3, ///< Request A/D conversion from ADC unit 1 at down counting compare match of @ref gpt_extended_pwm_cfg_t::adc_b_compare_match
+} gpt_adc_trigger_t;
+
+/** POEG channel to link to this channel. */
+typedef enum e_gpt_poeg_link
+{
+    GPT_POEG_LINK_POEG0 = 0U,          ///< Link this GPT channel to POEG channel 0 (GTETRGA)
+    GPT_POEG_LINK_POEG1 = 1U,          ///< Link this GPT channel to POEG channel 1 (GTETRGB)
+    GPT_POEG_LINK_POEG2 = 2U,          ///< Link this GPT channel to POEG channel 2 (GTETRGC)
+    GPT_POEG_LINK_POEG3 = 3U,          ///< Link this GPT channel to POEG channel 3 (GTETRGD)
+} gpt_poeg_link_t;
+
+/** Select trigger to send output disable request to POEG. */
+typedef enum e_gpt_output_disable
+{
+    GPT_OUTPUT_DISABLE_NONE               = 0U,      ///< None - no output disable request
+    GPT_OUTPUT_DISABLE_DEAD_TIME_ERROR    = 1U << 0, ///< Request output disable if a dead time error occurs
+    GPT_OUTPUT_DISABLE_GTIOCA_GTIOCB_HIGH = 1U << 1, ///< Request output disable if GTIOCA and GTIOCB are high at the same time
+    GPT_OUTPUT_DISABLE_GTIOCA_GTIOCB_LOW  = 1U << 2, ///< Request output disable if GTIOCA and GTIOCB are low at the same time
+} gpt_output_disable_t;
+
+/** Disable level options for GTIOC pins. */
+typedef enum e_gpt_gtioc_disable
+{
+    GPT_GTIOC_DISABLE_PROHIBITED = 0U, ///< Do not allow output disable
+    GPT_GTIOC_DISABLE_SET_HI_Z   = 1U, ///< Set GTIOC to high impedance when output is disabled
+    GPT_GTIOC_DISABLE_LEVEL_LOW  = 2U, ///< Set GTIOC level low when output is disabled
+    GPT_GTIOC_DISABLE_LEVEL_HIGH = 3U, ///< Set GTIOC level high when output is disabled
+} gpt_gtioc_disable_t;
+
+/** Trigger options to start A/D conversion. */
+typedef enum e_gpt_adc_compare_match
+{
+    GPT_ADC_COMPARE_MATCH_ADC_A = 0U,  ///< Set A/D conversion start request value for GPT A/D converter start request A
+    GPT_ADC_COMPARE_MATCH_ADC_B = 3U,  ///< Set A/D conversion start request value for GPT A/D converter start request B
+} gpt_adc_compare_match_t;
+
+/** Interrupt skipping modes */
+typedef enum e_gpt_interrupt_skip_source
+{
+    GPT_INTERRUPT_SKIP_SOURCE_NONE               = 0U, ///< Do not skip interrupts
+    GPT_INTERRUPT_SKIP_SOURCE_OVERFLOW_UNDERFLOW = 1U, ///< Count and skip overflow and underflow interrupts
+
+    /** Count crest interrupts for interrupt skipping. Skip the number of crest and trough interrupts configured in
+     *  @ref gpt_interrupt_skip_count_t. When the interrupt does fire, the trough interrupt fires before the crest
+     * interrupt. */
+    GPT_INTERRUPT_SKIP_SOURCE_CREST = 1U,
+
+    /** Count trough interrupts for interrupt skipping. Skip the number of crest and trough interrupts configured in
+     *  @ref gpt_interrupt_skip_count_t. When the interrupt does fire, the crest interrupt fires before the trough
+     *  interrupt. */
+    GPT_INTERRUPT_SKIP_SOURCE_TROUGH = 2U,
+} gpt_interrupt_skip_source_t;
+
+/** Number of interrupts to skip between events */
+typedef enum e_gpt_interrupt_skip_count
+{
+    GPT_INTERRUPT_SKIP_COUNT_0 = 0U,   ///< Do not skip interrupts
+    GPT_INTERRUPT_SKIP_COUNT_1,        ///< Skip one interrupt
+    GPT_INTERRUPT_SKIP_COUNT_2,        ///< Skip two interrupts
+    GPT_INTERRUPT_SKIP_COUNT_3,        ///< Skip three interrupts
+    GPT_INTERRUPT_SKIP_COUNT_4,        ///< Skip four interrupts
+    GPT_INTERRUPT_SKIP_COUNT_5,        ///< Skip five interrupts
+    GPT_INTERRUPT_SKIP_COUNT_6,        ///< Skip six interrupts
+    GPT_INTERRUPT_SKIP_COUNT_7,        ///< Skip seven interrupts
+
+    /** When setting GTIEITC */
+    GPT_INTERRUPT_SKIP_COUNT_8,        ///< Skip eight interrupts
+    GPT_INTERRUPT_SKIP_COUNT_9,        ///< Skip nine interrupts
+    GPT_INTERRUPT_SKIP_COUNT_10,       ///< Skip ten interrupts
+    GPT_INTERRUPT_SKIP_COUNT_11,       ///< Skip eleven interrupts
+    GPT_INTERRUPT_SKIP_COUNT_12,       ///< Skip twelve interrupts
+    GPT_INTERRUPT_SKIP_COUNT_13,       ///< Skip thiertenn interrupts
+    GPT_INTERRUPT_SKIP_COUNT_14,       ///< Skip fourteen interrupts
+    GPT_INTERRUPT_SKIP_COUNT_15,       ///< Skip fifteen interrupts
+} gpt_interrupt_skip_count_t;
+
+/** ADC events to skip during interrupt skipping */
+typedef enum e_gpt_interrupt_skip_adc
+{
+    GPT_INTERRUPT_SKIP_ADC_NONE    = 0U, ///< Do not skip ADC events
+    GPT_INTERRUPT_SKIP_ADC_A       = 1U, ///< Skip ADC A events
+    GPT_INTERRUPT_SKIP_ADC_B       = 4U, ///< Skip ADC B events
+    GPT_INTERRUPT_SKIP_ADC_A_AND_B = 5U, ///< Skip ADC A and B events
+} gpt_interrupt_skip_adc_t;
+
+/** extended interrupt skipping */
+typedef enum e_gpt_interrupt_skip_select
+{
+    GPT_INTERRUPT_SKIP_SELECT_NONE      = 0U, ///< Do not perform an extended interrupt skipping
+    GPT_INTERRUPT_SKIP_SELECT_EITCNT1   = 1U, ///< An interrupt is output in the period of EITCNT1[3:0] bits = 0000b.
+    GPT_INTERRUPT_SKIP_SELECT_EITCNT2   = 2U, ///< An interrupt is output in the period of EITCNT2[3:0] bits = 0000b.
+    GPT_INTERRUPT_SKIP_SELECT_EITCNT1_2 = 3U, ///< An interrupt is output in the period of EITCNT1[3:0] bits = 0000b and EITCNT2[3:0] bits = 0000b.
+
+    GPT_INTERRUPT_SKIP_SELECT_EITVTT1   = 5U, ///< An interrupt is output in the period of EITCNT1[3:0] bits = EIVTT1[3:0] bits.
+    GPT_INTERRUPT_SKIP_SELECT_EITVTT2   = 6U, ///< An interrupt is output in the period of EITCNT2[3:0] bits = EIVTT2[3:0] bits.
+    GPT_INTERRUPT_SKIP_SELECT_EITVTT1_2 = 7U, ///< An interrupt is output in the period of EITCNT1[3:0] bits = EIVTT1[3:0] bits and EITCNT2[3:0] bits = EIVTT2[3:0] bits.
+} gpt_interrupt_skip_select_t;
+
+/** Channel control block. DO NOT INITIALIZE.  Initialization occurs when @ref timer_api_t::open is called. */
+typedef struct st_gpt_instance_ctrl
+{
+    uint32_t            open;                     // Whether or not channel is open
+    const timer_cfg_t * p_cfg;                    // Pointer to initial configurations
+    R_GPT0_Type       * p_reg;                    // Base register for this channel
+    uint32_t            channel_mask;             // Channel bitmask
+    timer_variant_t     variant;                  // Timer variant
+
+    void (* p_callback)(timer_callback_args_t *); // Pointer to callback
+    timer_callback_args_t * p_callback_memory;    // Pointer to optional callback argument memory
+    void const            * p_context;            // Pointer to context to be passed into callback function
+} gpt_instance_ctrl_t;
+
+/** GPT extension for advanced PWM features. */
+typedef struct st_gpt_extended_pwm_cfg
+{
+    uint8_t                     trough_ipl;                 ///< Trough interrupt priority
+    IRQn_Type                   trough_irq;                 ///< Trough interrupt
+    gpt_poeg_link_t             poeg_link;                  ///< Select which POEG channel controls output disable for this GPT channel
+    gpt_output_disable_t        output_disable;             ///< Select which trigger sources request output disable from POEG
+    gpt_adc_trigger_t           adc_trigger;                ///< Select trigger sources to start A/D conversion
+    uint32_t                    dead_time_count_up;         ///< Set a dead time value for counting up
+    uint32_t                    dead_time_count_down;       ///< Set a dead time value for counting down
+    uint32_t                    adc_a_compare_match;        ///< Select the compare match value used to trigger an A/D conversion start request using ELC_EVENT_GPT<channel>_AD_TRIG_A
+    uint32_t                    adc_b_compare_match;        ///< Select the compare match value used to trigger an A/D conversion start request using ELC_EVENT_GPT<channel>_AD_TRIG_B
+    gpt_interrupt_skip_source_t interrupt_skip_source;      ///< Interrupt source to count for interrupt skipping
+    gpt_interrupt_skip_count_t  interrupt_skip_count;       ///< Number of interrupts to skip between events
+    gpt_interrupt_skip_adc_t    interrupt_skip_adc;         ///< ADC events to skip when interrupt skipping is enabled
+    gpt_interrupt_skip_source_t interrupt_skip_source_ext1; ///< Interrupt source to count for interrupt skipping(GTEITC.EIVTC1)
+    gpt_interrupt_skip_count_t  interrupt_skip_count_ext1;  ///< Number of interrupts to skip between events(GTEITC.EIVTT1)
+    gpt_interrupt_skip_source_t interrupt_skip_source_ext2; ///< Interrupt source to count for interrupt skipping(GTEITC.EIVTC2)
+    gpt_interrupt_skip_count_t  interrupt_skip_count_ext2;  ///< Number of interrupts to skip between events(GTEITC.EIVTT2)
+    gpt_interrupt_skip_select_t interrupt_skip_func_ovf;    ///< Extended Skipping Function Select(GTEITL1.EITVL)
+    gpt_interrupt_skip_select_t interrupt_skip_func_unf;    ///< Extended Skipping Function Select(GTEITL1.EITUL)
+    gpt_interrupt_skip_select_t interrupt_skip_func_adc_a;  ///< Extended Skipping Function Select(GTEITL2.EADTAL)
+    gpt_interrupt_skip_select_t interrupt_skip_func_adc_b;  ///< Extended Skipping Function Select(GTEITL2.EADTBL)
+    gpt_gtioc_disable_t         gtioca_disable_setting;     ///< Select how to configure GTIOCA when output is disabled
+    gpt_gtioc_disable_t         gtiocb_disable_setting;     ///< Select how to configure GTIOCB when output is disabled
+} gpt_extended_pwm_cfg_t;
+
+/** GPT extension configures the output pins for GPT. */
+typedef struct st_gpt_extended_cfg
+{
+    gpt_output_pin_t gtioca;           ///< Configuration for GPT I/O pin A
+    gpt_output_pin_t gtiocb;           ///< Configuration for GPT I/O pin B
+    gpt_source_t     start_source;     ///< Event sources that trigger the timer to start
+    gpt_source_t     stop_source;      ///< Event sources that trigger the timer to stop
+    gpt_source_t     clear_source;     ///< Event sources that trigger the timer to clear
+    gpt_source_t     capture_a_source; ///< Event sources that trigger capture of GTIOCA
+    gpt_source_t     capture_b_source; ///< Event sources that trigger capture of GTIOCB
+
+    /** Event sources that trigger a single up count. If GPT_SOURCE_NONE is selected for both count_up_source
+     * and count_down_source, then the timer count source is PCLK.  */
+    gpt_source_t count_up_source;
+
+    /** Event sources that trigger a single down count. If GPT_SOURCE_NONE is selected for both count_up_source
+     * and count_down_source, then the timer count source is PCLK.  */
+    gpt_source_t count_down_source;
+
+    gpt_capture_filter_t capture_filter_gtioca; ///< Debounce filter for GTIOCxA input signal pin.
+
+    gpt_capture_filter_t capture_filter_gtiocb; ///< Debounce filter for GTIOCxB input signal pin.
+
+    uint8_t capture_a_ipl;                      ///< Capture A interrupt priority
+    uint8_t capture_b_ipl;                      ///< Capture B interrupt priority
+    uint8_t dead_time_ipl;                      ///< Dead time error interrupt priority
+
+    uint8_t icds;                               ///< Input Capture Operation Select at Count Stop
+
+    IRQn_Type capture_a_irq;                    ///< Capture A interrupt
+    IRQn_Type capture_b_irq;                    ///< Capture B interrupt
+    IRQn_Type dead_time_irq;                    ///< Dead time error interrupt
+
+    gpt_extended_pwm_cfg_t const * p_pwm_cfg;   ///< Advanced PWM features, optional
+} gpt_extended_cfg_t;
+
+/**********************************************************************************************************************
+ * Exported global variables
+ **********************************************************************************************************************/
+
+/** @cond INC_HEADER_DEFS_SEC */
+/** Filled in Interface API structure for this Instance. */
+extern const timer_api_t g_timer_on_gpt;
+
+/** @endcond */
+
+/***********************************************************************************************************************
+ * Public APIs
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Open(timer_ctrl_t * const p_ctrl, timer_cfg_t const * const p_cfg);
+fsp_err_t R_GPT_Stop(timer_ctrl_t * const p_ctrl);
+fsp_err_t R_GPT_Start(timer_ctrl_t * const p_ctrl);
+fsp_err_t R_GPT_Reset(timer_ctrl_t * const p_ctrl);
+fsp_err_t R_GPT_Enable(timer_ctrl_t * const p_ctrl);
+fsp_err_t R_GPT_Disable(timer_ctrl_t * const p_ctrl);
+fsp_err_t R_GPT_PeriodSet(timer_ctrl_t * const p_ctrl, uint32_t const period_counts);
+fsp_err_t R_GPT_DutyCycleSet(timer_ctrl_t * const p_ctrl, uint32_t const duty_cycle_counts, uint32_t const pin);
+fsp_err_t R_GPT_InfoGet(timer_ctrl_t * const p_ctrl, timer_info_t * const p_info);
+fsp_err_t R_GPT_StatusGet(timer_ctrl_t * const p_ctrl, timer_status_t * const p_status);
+fsp_err_t R_GPT_CounterSet(timer_ctrl_t * const p_ctrl, uint32_t counter);
+fsp_err_t R_GPT_OutputEnable(timer_ctrl_t * const p_ctrl, gpt_io_pin_t pin);
+fsp_err_t R_GPT_OutputDisable(timer_ctrl_t * const p_ctrl, gpt_io_pin_t pin);
+fsp_err_t R_GPT_AdcTriggerSet(timer_ctrl_t * const    p_ctrl,
+                              gpt_adc_compare_match_t which_compare_match,
+                              uint32_t                compare_match_value);
+fsp_err_t R_GPT_CallbackSet(timer_ctrl_t * const          p_ctrl,
+                            void (                      * p_callback)(timer_callback_args_t *),
+                            void const * const            p_context,
+                            timer_callback_args_t * const p_callback_memory);
+fsp_err_t R_GPT_Close(timer_ctrl_t * const p_ctrl);
+
+/*******************************************************************************************************************//**
+ * @} (end defgroup GPT)
+ **********************************************************************************************************************/
+
+/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
+FSP_FOOTER
+
+#endif

+ 1089 - 0
projects/etherkit_ethercat_coe/rzn/fsp/src/r_canfd/r_canfd.c

@@ -0,0 +1,1089 @@
+/***********************************************************************************************************************
+ * Copyright [2020-2024] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
+ *
+ * This software and documentation are supplied by Renesas Electronics Corporation and/or its affiliates and may only
+ * be used with products of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.
+ * Renesas products are sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for
+ * the selection and use of Renesas products and Renesas assumes no liability.  No license, express or implied, to any
+ * intellectual property right is granted by Renesas.  This software is protected under all applicable laws, including
+ * copyright laws. Renesas reserves the right to change or discontinue this software and/or this documentation.
+ * THE SOFTWARE AND DOCUMENTATION IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND
+ * TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY,
+ * INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE
+ * SOFTWARE OR DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR
+ * DOCUMENTATION (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER,
+ * INCLUDING, WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY
+ * LOST PROFITS, OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+#include "r_canfd.h"
+#include "r_canfd_cfg.h"
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+
+#define CANFD_OPEN                             (0x52434644U) // "RCFD" in ASCII
+
+#define CANFD_BAUD_RATE_PRESCALER_MIN          (1U)
+#define CANFD_BAUD_RATE_PRESCALER_MAX          (1024U)
+
+#define CANFD_PRV_CTR_MODE_MASK                (R_CANFD_CFDGCTR_GSLPR_Msk + R_CANFD_CFDGCTR_GMDC_Msk)
+#define CANFD_PRV_CTR_RESET_BIT                (1U)
+#define CANFD_PRV_RX_FIFO_MAX                  (8U)
+#define CANFD_PRV_RX_BUFFER_RAM_LIMIT_BYTES    (4864U)
+#define CANFD_PRV_RXMB_MAX                     (32U)
+#define CANFD_PRV_TXMB_OFFSET                  (32U)
+#define CANFD_PRV_TXMB_CHANNEL_OFFSET          (64U)
+#define CANFD_PRV_STANDARD_ID_MAX              (0x7FFU)
+
+/***********************************************************************************************************************
+ * Const data
+ **********************************************************************************************************************/
+
+/* LUT to convert DLC values to payload size in bytes */
+static const uint8_t dlc_to_bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
+
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+
+/* LUT to determine the hierarchy of can_operation_mode_t modes. */
+static const uint8_t g_mode_order[] = {0, 2, 1, 0, 0, 3};
+#endif
+
+/***********************************************************************************************************************
+ * Private function prototypes
+ **********************************************************************************************************************/
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+static bool r_canfd_bit_timing_parameter_check(can_bit_timing_cfg_t * p_bit_timing, bool is_data_phase);
+
+#endif
+
+static void    r_canfd_mb_read(uint32_t buffer, can_frame_t * const frame);
+static void    r_canfd_call_callback(canfd_instance_ctrl_t * p_instance_ctrl, can_callback_args_t * p_args);
+static void    r_canfd_mode_transition(canfd_instance_ctrl_t * p_instance_ctrl, can_operation_mode_t operation_mode);
+static void    r_canfd_mode_ctr_set(volatile uint32_t * p_ctr_reg, can_operation_mode_t operation_mode);
+static uint8_t r_canfd_bytes_to_dlc(uint8_t bytes);
+void           canfd_error_isr(void);
+void           canfd_rx_fifo_isr(void);
+void           canfd_channel_tx_isr(void);
+
+/***********************************************************************************************************************
+ * ISR prototypes
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Private global variables
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Global Variables
+ **********************************************************************************************************************/
+
+/* Channel control struct array */
+static canfd_instance_ctrl_t * gp_instance_ctrl[BSP_FEATURE_CANFD_NUM_CHANNELS] = {NULL};
+
+/* CAN function pointers   */
+const can_api_t g_canfd_on_canfd =
+{
+    .open           = R_CANFD_Open,
+    .close          = R_CANFD_Close,
+    .write          = R_CANFD_Write,
+    .read           = R_CANFD_Read,
+    .modeTransition = R_CANFD_ModeTransition,
+    .infoGet        = R_CANFD_InfoGet,
+    .callbackSet    = R_CANFD_CallbackSet,
+};
+
+/*******************************************************************************************************************//**
+ * @addtogroup CANFD
+ * @{
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Functions
+ **********************************************************************************************************************/
+
+/***************************************************************************************************************//**
+ * Open and configure the CANFD channel for operation.
+ *
+ * @retval FSP_SUCCESS                            Channel opened successfully.
+ * @retval FSP_ERR_ALREADY_OPEN                   Driver already open.
+ * @retval FSP_ERR_IN_USE                         Channel is already in use.
+ * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT         Channel does not exist on this MCU.
+ * @retval FSP_ERR_ASSERTION                      A required pointer was NULL.
+ * @retval FSP_ERR_CAN_INIT_FAILED                The provided nominal or data bitrate is invalid.
+ *****************************************************************************************************************/
+fsp_err_t R_CANFD_Open (can_ctrl_t * const p_ctrl, can_cfg_t const * const p_cfg)
+{
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) p_ctrl;
+
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(p_instance_ctrl);
+    FSP_ASSERT(p_cfg);
+    FSP_ASSERT(p_cfg->p_extend);
+    FSP_ASSERT(p_cfg->p_callback);
+    FSP_ASSERT(p_cfg->p_bit_timing);
+
+    /* Check that the module is not open, the channel is present and that it is not in use */
+    FSP_ERROR_RETURN(CANFD_OPEN != p_instance_ctrl->open, FSP_ERR_ALREADY_OPEN);
+    FSP_ERROR_RETURN(p_cfg->channel < 2, FSP_ERR_IP_CHANNEL_NOT_PRESENT);
+    FSP_ERROR_RETURN(NULL == gp_instance_ctrl[p_cfg->channel], FSP_ERR_IN_USE);
+
+    /* Check that mandatory interrupts are enabled */
+    FSP_ERROR_RETURN(VECTOR_NUMBER_CAN_RXF >= 0, FSP_ERR_CAN_INIT_FAILED);
+    FSP_ERROR_RETURN(VECTOR_NUMBER_CAN_GLERR >= 0, FSP_ERR_CAN_INIT_FAILED);
+
+    /* Check that the global config is present */
+    canfd_extended_cfg_t * p_extend = (canfd_extended_cfg_t *) p_cfg->p_extend;
+    FSP_ASSERT(p_extend->p_global_cfg);
+
+    /* Check nominal bit timing parameters for correctness */
+    FSP_ERROR_RETURN(r_canfd_bit_timing_parameter_check(p_cfg->p_bit_timing, false), FSP_ERR_CAN_INIT_FAILED);
+
+    /* Check that bit timing for FD bitrate switching is present and correct */
+    can_bit_timing_cfg_t * p_data_timing = p_extend->p_data_timing;
+    FSP_ASSERT(p_data_timing);
+    FSP_ERROR_RETURN(r_canfd_bit_timing_parameter_check(p_data_timing, true), FSP_ERR_CAN_INIT_FAILED);
+
+    can_bit_timing_cfg_t * p_bit_timing = p_cfg->p_bit_timing;
+
+    /* Check that data rate > nominal rate */
+    uint32_t data_rate_clocks = p_data_timing->baud_rate_prescaler *
+                                (p_data_timing->time_segment_1 + p_data_timing->time_segment_2 + 1U);
+    uint32_t nominal_rate_clocks = p_bit_timing->baud_rate_prescaler *
+                                   (p_bit_timing->time_segment_1 + p_bit_timing->time_segment_2 + 1U);
+    FSP_ERROR_RETURN(data_rate_clocks <= nominal_rate_clocks, FSP_ERR_CAN_INIT_FAILED);
+#else
+
+    /* Get extended config */
+    canfd_extended_cfg_t * p_extend = (canfd_extended_cfg_t *) p_cfg->p_extend;
+#endif
+
+    fsp_err_t err = FSP_SUCCESS;
+
+    /* Initialize the control block */
+    p_instance_ctrl->p_cfg = p_cfg;
+
+    /* Set callback and context pointers, if configured */
+    p_instance_ctrl->p_callback        = p_cfg->p_callback;
+    p_instance_ctrl->p_context         = p_cfg->p_context;
+    p_instance_ctrl->p_callback_memory = NULL;
+
+    /* Get global config */
+    canfd_global_cfg_t * p_global_cfg = p_extend->p_global_cfg;
+
+    /* Start module */
+    R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_LPC_RESET);
+    R_BSP_MODULE_START(FSP_IP_CANFD, 0);
+    R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_LPC_RESET);
+
+    /* Perform global config only if the module is in Global Sleep or Global Reset */
+    if (R_CANFD->CFDGSTS & R_CANFD_CFDGSTS_GRSTSTS_Msk)
+    {
+        /* Wait for RAM initialization
+         *(see RZ microprocessor User's Manual section "Timing of Global Mode Change") */
+        FSP_HARDWARE_REGISTER_WAIT((R_CANFD->CFDGSTS & R_CANFD_CFDGSTS_GRAMINIT_Msk), 0);
+
+        /* Cancel Global Sleep and wait for transition to Global Reset */
+        r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_GLOBAL_RESET);
+
+        /* Configure global TX priority, DLC check/replace functions, external/internal clock select and payload
+         * overflow behavior */
+        R_CANFD->CFDGCFG = p_global_cfg->global_config;
+
+        /* Configure rule count for both channels */
+        R_CANFD->CFDGAFLCFG0 = (CANFD_CFG_AFL_CH0_RULE_NUM << R_CANFD_CFDGAFLCFG0_RNC0_Pos) |
+                               CANFD_CFG_AFL_CH1_RULE_NUM;
+
+        /* Set CAN FD Protocol Exception response (ISO exception state or send error frame) */
+        R_CANFD->CFDGFDCFG = CANFD_CFG_FD_PROTOCOL_EXCEPTION;
+
+        /* Set number and size of RX message buffers */
+        R_CANFD->CFDRMNB = p_global_cfg->rx_mb_config;
+
+        /* Configure RX FIFOs and interrupt */
+        for (uint32_t i = 0; i < CANFD_PRV_RX_FIFO_MAX; i++)
+        {
+            R_CANFD->CFDRFCC[i] = p_global_cfg->rx_fifo_config[i];
+        }
+
+        R_BSP_IrqCfgEnable(VECTOR_NUMBER_CAN_RXF, p_global_cfg->rx_fifo_ipl, NULL);
+
+        /* Set global error interrupts */
+        R_CANFD->CFDGCTR = p_global_cfg->global_interrupts;
+    }
+
+    if (CANFD_CFG_GLOBAL_ERROR_CH == p_cfg->channel)
+    {
+        /* Configure global error interrupt */
+        R_BSP_IrqCfgEnable(VECTOR_NUMBER_CAN_GLERR, p_global_cfg->global_err_ipl, NULL);
+    }
+
+    /* Track ctrl struct */
+    gp_instance_ctrl[p_cfg->channel] = p_instance_ctrl;
+
+    /* Get AFL entry and limit */
+    uint32_t afl_entry = 0;
+    uint32_t afl_max   = CANFD_CFG_AFL_CH0_RULE_NUM;
+    if (1U == p_cfg->channel)
+    {
+        afl_entry += CANFD_CFG_AFL_CH0_RULE_NUM;
+        afl_max   += CANFD_CFG_AFL_CH1_RULE_NUM;
+    }
+
+    /* Unlock AFL */
+    R_CANFD->CFDGAFLECTR = R_CANFD_CFDGAFLECTR_AFLDAE_Msk;
+
+    /* Write all configured AFL entries */
+    R_CANFD_CFDGAFL_Type * p_afl = (R_CANFD_CFDGAFL_Type *) p_extend->p_afl;
+    for ( ; afl_entry < afl_max; afl_entry++)
+    {
+        /* AFL register access is performed through a page window comprised of 16 entries. See Section "Entering
+         * Entries in the AFL" in the RZ microprocessor User's Manual for more details. */
+
+        /* Set AFL page */
+        R_CANFD->CFDGAFLECTR = (afl_entry >> 4) | R_CANFD_CFDGAFLECTR_AFLDAE_Msk;
+
+        /* Get pointer to current AFL rule and set it to the rule pointed to by p_afl */
+        volatile R_CANFD_CFDGAFL_Type * cfdgafl = &R_CANFD->CFDGAFL[afl_entry & 0xF];
+        *cfdgafl = *p_afl++;
+
+        /* Set Information Label 0 to the channel being configured */
+        cfdgafl->P0_b.GAFLIFL0 = p_cfg->channel & 1U;
+    }
+
+    /* Lock AFL */
+    R_CANFD->CFDGAFLECTR = 0;
+
+    /* Cancel Channel Sleep and wait for transition to Channel Reset */
+    r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_RESET);
+
+    /* Configure bitrate */
+    R_CANFD->CFDC[p_cfg->channel].NCFG =
+        (uint32_t) (((p_cfg->p_bit_timing->baud_rate_prescaler - 1) & R_CANFD_CFDC_NCFG_NBRP_Msk) <<
+                    R_CANFD_CFDC_NCFG_NBRP_Pos) |
+        ((p_cfg->p_bit_timing->time_segment_1 - 1U) << R_CANFD_CFDC_NCFG_NTSEG1_Pos) |
+        ((p_cfg->p_bit_timing->time_segment_2 - 1U) << R_CANFD_CFDC_NCFG_NTSEG2_Pos) |
+        ((p_cfg->p_bit_timing->synchronization_jump_width - 1U) << R_CANFD_CFDC_NCFG_NSJW_Pos);
+
+    /* Configure data bitrate for rate switching on FD frames */
+    R_CANFD->CFDC2[p_cfg->channel].DCFG =
+        (uint32_t) (((p_extend->p_data_timing->baud_rate_prescaler - 1) & R_CANFD_CFDC2_DCFG_DBRP_Msk) <<
+                    R_CANFD_CFDC2_DCFG_DBRP_Pos) |
+        ((p_extend->p_data_timing->time_segment_1 - 1U) << R_CANFD_CFDC2_DCFG_DTSEG1_Pos) |
+        ((p_extend->p_data_timing->time_segment_2 - 1U) << R_CANFD_CFDC2_DCFG_DTSEG2_Pos) |
+        ((p_extend->p_data_timing->synchronization_jump_width - 1U) << R_CANFD_CFDC2_DCFG_DSJW_Pos);
+
+    /* Ensure transceiver delay offset is not larger than 8 bits */
+    uint32_t tdco = p_extend->p_data_timing->time_segment_1;
+    if (tdco > UINT8_MAX)
+    {
+        tdco = UINT8_MAX;
+    }
+
+    /* Configure transceiver delay compensation; allow user to set ESI bit manually
+     * Leave the CLOE bit at the default setting for each device product.
+     */
+    uint32_t cloe = R_CANFD->CFDC2[p_cfg->channel].FDCFG_b.CLOE;
+    R_CANFD->CFDC2[p_cfg->channel].FDCFG =
+        (cloe << R_CANFD_CFDC2_FDCFG_CLOE_Pos) |
+        (tdco << R_CANFD_CFDC2_FDCFG_TDCO_Pos) |
+        (uint32_t) (p_extend->delay_compensation << R_CANFD_CFDC2_FDCFG_TDCE_Pos) |
+        R_CANFD_CFDC2_FDCFG_ESIC_Msk | 1U;
+
+    /* Write TX message buffer interrupt enable bits */
+    memcpy((void *) &R_CANFD->CFDTMIEC[p_cfg->channel * 2], &p_extend->txmb_txi_enable, 2 * sizeof(uint32_t));
+
+    /* Configure channel error interrupts */
+    R_CANFD->CFDC[p_cfg->channel].CTR = p_extend->error_interrupts | R_CANFD_CFDC_CTR_CHMDC_Msk;
+
+    /* Enable channel interrupts */
+
+    if (p_cfg->error_irq >= 0)
+    {
+        R_BSP_IrqCfgEnable(p_cfg->error_irq, p_cfg->ipl, p_instance_ctrl);
+    }
+
+    if (p_cfg->tx_irq >= 0)
+    {
+        R_BSP_IrqCfgEnable(p_cfg->tx_irq, p_cfg->ipl, p_instance_ctrl);
+    }
+
+    /* Set global mode to Operation and wait for transition */
+    r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_GLOBAL_OPERATION);
+
+    /* Transition to Channel Operation */
+    r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_NORMAL);
+
+    /* Set current operation modes */
+    p_instance_ctrl->operation_mode = CAN_OPERATION_MODE_NORMAL;
+    p_instance_ctrl->test_mode      = CAN_TEST_MODE_DISABLED;
+
+    /* Set driver to open */
+    p_instance_ctrl->open = CANFD_OPEN;
+
+    return err;
+}
+
+/***************************************************************************************************************//**
+ * Close the CANFD channel.
+ *
+ * @retval FSP_SUCCESS               Channel closed successfully.
+ * @retval FSP_ERR_NOT_OPEN          Control block not open.
+ * @retval FSP_ERR_ASSERTION         Null pointer presented.
+ *****************************************************************************************************************/
+fsp_err_t R_CANFD_Close (can_ctrl_t * const p_ctrl)
+{
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) p_ctrl;
+
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(p_instance_ctrl->open == CANFD_OPEN, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Get config struct */
+    can_cfg_t * p_cfg = (can_cfg_t *) p_instance_ctrl->p_cfg;
+
+    /* Disable channel interrupts */
+
+    if (p_cfg->error_irq >= 0)
+    {
+        R_BSP_IrqDisable(p_cfg->error_irq);
+    }
+
+    if (p_cfg->tx_irq >= 0)
+    {
+        R_BSP_IrqDisable(p_cfg->tx_irq);
+    }
+
+    /* Disable Global Error interrupt if the handler channel is being closed */
+    if (CANFD_CFG_GLOBAL_ERROR_CH == p_cfg->channel)
+    {
+        R_BSP_IrqDisable(VECTOR_NUMBER_CAN_GLERR);
+    }
+
+    /* Set channel to Sleep if other is open, otherwise reset/stop CANFD module */
+    if (gp_instance_ctrl[!p_cfg->channel])
+    {
+        r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_SLEEP);
+    }
+    else
+    {
+        /* Disable RX FIFO interrupt */
+        R_BSP_IrqDisable(VECTOR_NUMBER_CAN_RXF);
+
+        /* Transition to Global Sleep */
+        r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_GLOBAL_RESET);
+        r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_GLOBAL_SLEEP);
+
+        /* Stop CANFD module */
+        R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_LPC_RESET);
+        R_BSP_MODULE_STOP(FSP_IP_CANFD, 0);
+        R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_LPC_RESET);
+    }
+
+    /* Reset global control struct pointer */
+    gp_instance_ctrl[p_cfg->channel] = NULL;
+
+    /* Set driver to closed */
+    p_instance_ctrl->open = 0U;
+
+    return FSP_SUCCESS;
+}
+
+/***************************************************************************************************************//**
+ * Write data to the CANFD channel.
+ *
+ * @retval FSP_SUCCESS                      Operation succeeded.
+ * @retval FSP_ERR_NOT_OPEN                 Control block not open.
+ * @retval FSP_ERR_CAN_TRANSMIT_NOT_READY   Transmit in progress, cannot write data at this time.
+ * @retval FSP_ERR_INVALID_ARGUMENT         Data length or buffer number invalid.
+ * @retval FSP_ERR_INVALID_MODE             An FD option was set on a non-FD frame.
+ * @retval FSP_ERR_ASSERTION                Null pointer presented
+ *****************************************************************************************************************/
+fsp_err_t R_CANFD_Write (can_ctrl_t * const p_ctrl, uint32_t buffer, can_frame_t * const p_frame)
+{
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) p_ctrl;
+
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ASSERT(NULL != p_frame);
+    FSP_ERROR_RETURN(p_instance_ctrl->open == CANFD_OPEN, FSP_ERR_NOT_OPEN);
+
+    /* CANFD channels have 32 TX message buffers each (0-15, 32-47) */
+    FSP_ERROR_RETURN((buffer <= 15U) || (buffer - 32U <= 15U), FSP_ERR_INVALID_ARGUMENT);
+
+    /* Check DLC field */
+    if (!(p_frame->options & CANFD_FRAME_OPTION_FD))
+    {
+        FSP_ERROR_RETURN(p_frame->data_length_code <= 8, FSP_ERR_INVALID_ARGUMENT);
+        FSP_ERROR_RETURN(p_frame->options == 0, FSP_ERR_INVALID_MODE);
+    }
+    else if (p_frame->data_length_code > 0)
+    {
+        /* Make sure the supplied data size corresponds to a valid DLC value */
+        FSP_ERROR_RETURN(0U != r_canfd_bytes_to_dlc(p_frame->data_length_code), FSP_ERR_INVALID_ARGUMENT);
+    }
+    else
+    {
+        /* Do nothing. */
+    }
+#endif
+
+    /* Calculate global TX message buffer number */
+    uint32_t txmb = buffer + (p_instance_ctrl->p_cfg->channel * CANFD_PRV_TXMB_CHANNEL_OFFSET);
+
+    /* Ensure MB is ready */
+    FSP_ERROR_RETURN(0U == R_CANFD->CFDTMSTS_b[txmb].TMTSTS, FSP_ERR_CAN_TRANSMIT_NOT_READY);
+
+    /* Set TX message buffer registers */
+    R_CANFD->CFDTM[txmb].ID = p_frame->id | ((uint32_t) p_frame->type << R_CANFD_CFDTM_ID_TMRTR_Pos) |
+                              ((uint32_t) p_frame->id_mode << R_CANFD_CFDTM_ID_TMIDE_Pos);
+    R_CANFD->CFDTM[txmb].PTR = (uint32_t) r_canfd_bytes_to_dlc(p_frame->data_length_code) <<
+                               R_CANFD_CFDTM_PTR_TMDLC_Pos;
+
+    /* Set FD bits (ESI, BRS and FDF) */
+    R_CANFD->CFDTM[txmb].FDCTR = p_frame->options & 7U;
+
+    /* Copy data to register buffer */
+    uint32_t           len    = p_frame->data_length_code;
+    volatile uint8_t * p_dest = (uint8_t *) R_CANFD->CFDTM[txmb].DF;
+    volatile uint8_t * p_src  = p_frame->data;
+    while (len--)
+    {
+        *p_dest++ = *p_src++;
+    }
+
+    /* Request transmission */
+    R_CANFD->CFDTMC[txmb] = 1;
+
+    return FSP_SUCCESS;
+}
+
+/***************************************************************************************************************//**
+ * Read data from a CANFD Message Buffer or FIFO.
+ *
+ * @retval FSP_SUCCESS                      Operation succeeded.
+ * @retval FSP_ERR_NOT_OPEN                 Control block not open.
+ * @retval FSP_ERR_INVALID_ARGUMENT         Buffer number invalid.
+ * @retval FSP_ERR_ASSERTION                p_ctrl or p_frame is NULL.
+ * @retval FSP_ERR_BUFFER_EMPTY             Buffer or FIFO is empty.
+ *****************************************************************************************************************/
+fsp_err_t R_CANFD_Read (can_ctrl_t * const p_ctrl, uint32_t buffer, can_frame_t * const p_frame)
+{
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) p_ctrl;
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ASSERT(NULL != p_frame);
+    FSP_ERROR_RETURN(p_instance_ctrl->open == CANFD_OPEN, FSP_ERR_NOT_OPEN);
+    FSP_ERROR_RETURN(buffer < CANFD_PRV_RXMB_MAX + CANFD_PRV_RX_FIFO_MAX, FSP_ERR_INVALID_ARGUMENT);
+#else
+    FSP_PARAMETER_NOT_USED(p_ctrl);
+#endif
+
+    uint32_t not_empty;
+
+    /* Return an error if the buffer or FIFO is empty */
+    if (buffer < CANFD_PRV_RXMB_MAX)
+    {
+        not_empty = R_CANFD->CFDRMND0 & (1U << buffer);
+    }
+    else
+    {
+        not_empty = !(R_CANFD->CFDFESTS & (1U << (buffer - CANFD_PRV_RXMB_MAX)));
+    }
+
+    FSP_ERROR_RETURN(not_empty, FSP_ERR_BUFFER_EMPTY);
+
+    /* Retrieve message from buffer */
+    r_canfd_mb_read(buffer, p_frame);
+
+    return FSP_SUCCESS;
+}
+
+/***************************************************************************************************************//**
+ * Switch to a different channel, global or test mode.
+ *
+ * @retval FSP_SUCCESS                      Operation succeeded.
+ * @retval FSP_ERR_NOT_OPEN                 Control block not open.
+ * @retval FSP_ERR_ASSERTION                Null pointer presented
+ * @retval FSP_ERR_INVALID_MODE             Cannot change to the requested mode from the current global mode.
+ *****************************************************************************************************************/
+fsp_err_t R_CANFD_ModeTransition (can_ctrl_t * const   p_ctrl,
+                                  can_operation_mode_t operation_mode,
+                                  can_test_mode_t      test_mode)
+{
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) p_ctrl;
+    fsp_err_t               err             = FSP_SUCCESS;
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(p_instance_ctrl->open == CANFD_OPEN, FSP_ERR_NOT_OPEN);
+
+    /* Get Global Status */
+    uint32_t cfdgsts = R_CANFD->CFDGSTS;
+
+    /* Check to ensure the current mode is Global Halt when transitioning into or out of Internal Bus mode */
+    FSP_ERROR_RETURN((cfdgsts & R_CANFD_CFDGSTS_GHLTSTS_Msk) || !((p_instance_ctrl->test_mode != test_mode) &&
+                                                                  ((CAN_TEST_MODE_INTERNAL_BUS ==
+                                                                    p_instance_ctrl->test_mode) ||
+                                                                   (CAN_TEST_MODE_INTERNAL_BUS == test_mode))),
+                     FSP_ERR_INVALID_MODE);
+
+    /* Check to ensure the current mode is Global Reset when transitioning into or out of Global Sleep (see Section
+     * "Global Modes" in the RZ microprocessor User's Manual for details) */
+    FSP_ERROR_RETURN(((cfdgsts & R_CANFD_CFDGSTS_GRSTSTS_Msk) && (CAN_OPERATION_MODE_RESET & operation_mode)) ||
+                     (!(cfdgsts & R_CANFD_CFDGSTS_GSLPSTS_Msk) && (CAN_OPERATION_MODE_GLOBAL_SLEEP != operation_mode)),
+                     FSP_ERR_INVALID_MODE);
+
+    /* Check to ensure the current Global mode supports the requested Channel mode, if applicable. The requested mode
+     * and the current global mode are converted into a number 0-3 corresponding to Operation, Halt, Reset and Sleep
+     * respectively. The channel mode cannot be switched to a mode with an index lower than the current global mode. */
+    if (operation_mode < CAN_OPERATION_MODE_GLOBAL_OPERATION)
+    {
+        FSP_ERROR_RETURN(g_mode_order[operation_mode] >= g_mode_order[cfdgsts & CANFD_PRV_CTR_MODE_MASK],
+                         FSP_ERR_INVALID_MODE);
+    }
+#endif
+
+    if (p_instance_ctrl->test_mode != test_mode)
+    {
+        /* Follow the procedure for switching to Internal Bus mode given in Section "Internal CAN Bus
+         * Communication Test Mode" of the RZ microprocessor User's Manual */
+        if (CAN_TEST_MODE_INTERNAL_BUS == test_mode)
+        {
+            /* Disable channel test mode */
+            R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].CTR_b.CTME = 0;
+
+            /* Link channel to internal bus */
+            R_CANFD->CFDGTSTCFG |= 1U << p_instance_ctrl->p_cfg->channel;
+
+            /* Enable internal bus test mode */
+            R_CANFD->CFDGTSTCTR = 1;
+        }
+        else
+        {
+            if (p_instance_ctrl->test_mode == CAN_TEST_MODE_INTERNAL_BUS)
+            {
+                /* Unlink channel from internal bus */
+                R_CANFD->CFDGTSTCFG &= ~(1U << p_instance_ctrl->p_cfg->channel);
+
+                /* Disable global test mode if no channels are linked */
+                if (!R_CANFD->CFDGTSTCFG)
+                {
+                    R_CANFD->CFDGTSTCTR = 0;
+                }
+            }
+
+            /* Transition to Channel Halt when changing test modes */
+            r_canfd_mode_transition(p_instance_ctrl, CAN_OPERATION_MODE_HALT);
+
+            /* Set channel test mode */
+            uint32_t cfdcnctr = R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].CTR;
+            cfdcnctr &= ~(R_CANFD_CFDC_CTR_CTME_Msk | R_CANFD_CFDC_CTR_CTMS_Msk);
+            R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].CTR = cfdcnctr |
+                                                                 ((uint32_t) test_mode << R_CANFD_CFDC_CTR_CTME_Pos);
+        }
+
+        p_instance_ctrl->test_mode = test_mode;
+    }
+
+    if (p_instance_ctrl->operation_mode != operation_mode)
+    {
+        r_canfd_mode_transition(p_instance_ctrl, operation_mode);
+    }
+
+    return err;
+}
+
+/***************************************************************************************************************//**
+ * Get CANFD state and status information for the channel.
+ *
+ * @retval  FSP_SUCCESS                     Operation succeeded.
+ * @retval  FSP_ERR_NOT_OPEN                Control block not open.
+ * @retval  FSP_ERR_ASSERTION               Null pointer presented
+ *****************************************************************************************************************/
+fsp_err_t R_CANFD_InfoGet (can_ctrl_t * const p_ctrl, can_info_t * const p_info)
+{
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) p_ctrl;
+
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+
+    /* Check pointers for NULL values */
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ASSERT(NULL != p_info);
+
+    /* If channel is not open, return an error */
+    FSP_ERROR_RETURN(p_instance_ctrl->open == CANFD_OPEN, FSP_ERR_NOT_OPEN);
+#endif
+
+    uint32_t cfdcnsts = R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].STS;
+    p_info->status               = cfdcnsts & UINT16_MAX;
+    p_info->error_count_receive  = (uint8_t) ((cfdcnsts & R_CANFD_CFDC_STS_REC_Msk) >> R_CANFD_CFDC_STS_REC_Pos);
+    p_info->error_count_transmit = (uint8_t) ((cfdcnsts & R_CANFD_CFDC_STS_TEC_Msk) >> R_CANFD_CFDC_STS_TEC_Pos);
+    p_info->error_code           = R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].ERFL & UINT16_MAX;
+    p_info->rx_mb_status         = R_CANFD->CFDRMND0;
+    p_info->rx_fifo_status       = (~R_CANFD->CFDFESTS) & R_CANFD_CFDFESTS_RFXEMP_Msk;
+
+    /* Clear error flags */
+    R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].ERFL &= ~((uint32_t) UINT16_MAX);
+
+    /* Dummy read to ensure that interrupt event is cleared. */
+    volatile uint32_t dummy = R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].ERFL;
+    FSP_PARAMETER_NOT_USED(dummy);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Updates the user callback with the option to provide memory for the callback argument structure.
+ * Implements @ref can_api_t::callbackSet.
+ *
+ * @retval  FSP_SUCCESS                  Callback updated successfully.
+ * @retval  FSP_ERR_ASSERTION            A required pointer is NULL.
+ * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
+ **********************************************************************************************************************/
+fsp_err_t R_CANFD_CallbackSet (can_ctrl_t * const          p_ctrl,
+                               void (                    * p_callback)(can_callback_args_t *),
+                               void const * const          p_context,
+                               can_callback_args_t * const p_callback_memory)
+{
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) p_ctrl;
+
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(p_instance_ctrl);
+    FSP_ASSERT(p_callback);
+    FSP_ERROR_RETURN(CANFD_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Store callback and context */
+    p_instance_ctrl->p_callback        = p_callback;
+    p_instance_ctrl->p_context         = p_context;
+    p_instance_ctrl->p_callback_memory = p_callback_memory;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * @} (end addtogroup CAN)
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Private Functions
+ **********************************************************************************************************************/
+#if CANFD_CFG_PARAM_CHECKING_ENABLE
+static bool r_canfd_bit_timing_parameter_check (can_bit_timing_cfg_t * const p_bit_timing, bool is_data_phase)
+{
+    /* Check that prescaler is in range */
+    FSP_ERROR_RETURN((p_bit_timing->baud_rate_prescaler <= CANFD_BAUD_RATE_PRESCALER_MAX) &&
+                     (p_bit_timing->baud_rate_prescaler >= CANFD_BAUD_RATE_PRESCALER_MIN),
+                     false);
+
+    /* Check that TSEG1 > TSEG2 >= SJW for nominal bitrate per section "Bit Timing Conditions" in the
+     * RZ microprocessor User's Manual. */
+
+    if (is_data_phase)
+    {
+        /* Check Time Segment 1 is greater than or equal to Time Segment 2 */
+        FSP_ERROR_RETURN((uint32_t) p_bit_timing->time_segment_1 >= (uint32_t) p_bit_timing->time_segment_2, false);
+    }
+    else
+    {
+        /* Check Time Segment 1 is greater than Time Segment 2 */
+        FSP_ERROR_RETURN((uint32_t) p_bit_timing->time_segment_1 > (uint32_t) p_bit_timing->time_segment_2, false);
+    }
+
+    /* Check Time Segment 2 is greater than or equal to the synchronization jump width */
+    FSP_ERROR_RETURN((uint32_t) p_bit_timing->time_segment_2 >= (uint32_t) p_bit_timing->synchronization_jump_width,
+                     false);
+
+    return true;
+}
+
+#endif
+
+/*******************************************************************************************************************//**
+ * Read from a Message Buffer or FIFO.
+ *
+ * NOTE: Does not index FIFOs.
+ *
+ * @param[in]     buffer     Index of buffer to read from (MBs 0-31, FIFOs 32+)
+ * @param[in]     frame      Pointer to CAN frame to write to
+ **********************************************************************************************************************/
+static void r_canfd_mb_read (uint32_t buffer, can_frame_t * const frame)
+{
+    bool is_mb = buffer < CANFD_PRV_RXMB_MAX;
+
+    /* Get pointer to message buffer (FIFOs use the same buffer structure) */
+    volatile R_CANFD_CFDRM_Type * mb_regs =
+        (is_mb) ? &(R_CANFD->CFDRM[buffer]) :
+        (volatile R_CANFD_CFDRM_Type *) &(R_CANFD->CFDRF[buffer - CANFD_PRV_RXMB_MAX]);
+
+    /* Get frame data. */
+    uint32_t id = mb_regs->ID;
+
+    /* Get the frame type */
+    frame->type = (can_frame_type_t) ((id & R_CANFD_CFDRM_ID_RMRTR_Msk) >> R_CANFD_CFDRM_ID_RMRTR_Pos);
+
+    /* Get FD status bits (ESI, BRS and FDF) */
+    frame->options = mb_regs->FDSTS & 7U;
+
+    /* Get the frame ID */
+    frame->id = id & R_CANFD_CFDRM_ID_RMID_Msk;
+
+    /* Get the frame ID mode (IDE bit) */
+    frame->id_mode = (can_id_mode_t) (id >> R_CANFD_CFDRM_ID_RMIDE_Pos);
+
+    /* Get the frame data length code */
+    frame->data_length_code = dlc_to_bytes[mb_regs->PTR >> R_CANFD_CFDRM_PTR_RMDLC_Pos];
+
+    /* Copy data to frame */
+    uint32_t           len    = frame->data_length_code;
+    volatile uint8_t * p_dest = frame->data;
+    volatile uint8_t * p_src  = (uint8_t *) mb_regs->DF;
+    while (len--)
+    {
+        *p_dest++ = *p_src++;
+    }
+
+    if (is_mb)
+    {
+        /* Clear RXMB New Data bit */
+        R_CANFD->CFDRMND0 &= ~(1U << buffer);
+    }
+    else
+    {
+        /* Increment RX FIFO pointer */
+        R_CANFD->CFDRFPCTR[buffer - CANFD_PRV_RXMB_MAX] = UINT8_MAX;
+    }
+}
+
+/*******************************************************************************************************************//**
+ * Calls user callback.
+ *
+ * @param[in]     p_instance_ctrl     Pointer to CAN instance control block
+ * @param[in]     p_args              Pointer to arguments on stack
+ **********************************************************************************************************************/
+static void r_canfd_call_callback (canfd_instance_ctrl_t * p_instance_ctrl, can_callback_args_t * p_args)
+{
+    can_callback_args_t args;
+
+    /* Store callback arguments in memory provided by user if available. */
+    can_callback_args_t * p_args_memory = p_instance_ctrl->p_callback_memory;
+    if (NULL == p_args_memory)
+    {
+        /* Use provided args struct on stack */
+        p_args_memory = p_args;
+    }
+    else
+    {
+        /* Save current arguments on the stack in case this is a nested interrupt. */
+        args = *p_args_memory;
+
+        /* Copy the stacked args to callback memory */
+        *p_args_memory = *p_args;
+    }
+
+    p_instance_ctrl->p_callback(p_args_memory);
+
+    if (NULL != p_instance_ctrl->p_callback_memory)
+    {
+        /* Restore callback memory in case this is a nested interrupt. */
+        *p_instance_ctrl->p_callback_memory = args;
+    }
+}
+
+/*******************************************************************************************************************//**
+ * Error ISR.
+ *
+ * Saves context if RTOS is used, clears interrupts, calls common error function, and restores context if RTOS is used.
+ **********************************************************************************************************************/
+void canfd_error_isr (void)
+{
+    CANFD_CFG_MULTIPLEX_INTERRUPT_ENABLE;
+
+    /* Save context if RTOS is used */
+    FSP_CONTEXT_SAVE;
+
+    /* Get IRQ and context */
+    IRQn_Type               irq             = R_FSP_CurrentIrqGet();
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
+
+    can_callback_args_t     args = {0U};
+    canfd_instance_ctrl_t * p_callback_ctrl;
+
+    if (VECTOR_NUMBER_CAN_GLERR == irq)
+    {
+        args.event = CAN_EVENT_ERR_GLOBAL;
+
+        /* Read global error flags. */
+        uint32_t cfdgerfl = R_CANFD->CFDGERFL;
+
+        /* Global errors are in the top halfword of canfd_error_t; move and preserve ECC error flags. */
+        args.error = ((cfdgerfl & UINT16_MAX) << 16) + ((cfdgerfl >> 16) << 28);
+
+        /* Clear global error flags. */
+        R_CANFD->CFDGERFL = 0;
+
+        /* Dummy read to ensure that interrupt event is cleared. */
+        volatile uint32_t dummy = R_CANFD->CFDGERFL;
+        FSP_PARAMETER_NOT_USED(dummy);
+
+        if (args.error & CANFD_ERROR_GLOBAL_MESSAGE_LOST)
+        {
+            /* Get lowest RX FIFO with Message Lost condition and clear the flag */
+            args.buffer = __CLZ(__RBIT(R_CANFD->CFDFMSTS));
+            R_CANFD->CFDRFSTS[args.buffer] &= ~R_CANFD_CFDRFSTS_RFMLT_Msk;
+
+            /* Dummy read to ensure that interrupt event is cleared. */
+            dummy = R_CANFD->CFDRFSTS[args.buffer];
+            FSP_PARAMETER_NOT_USED(dummy);
+        }
+
+        /* Choose ctrl block for the selected global error handler channel. */
+        p_callback_ctrl = gp_instance_ctrl[CANFD_CFG_GLOBAL_ERROR_CH];
+
+        /* Set channel and context based on selected global error handler channel. */
+        args.channel   = CANFD_CFG_GLOBAL_ERROR_CH;
+        args.p_context = p_callback_ctrl->p_context;
+    }
+    else
+    {
+        args.event = CAN_EVENT_ERR_CHANNEL;
+
+        /* Read and clear channel error flags. */
+        args.error = R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].ERFL & UINT16_MAX; // Upper halfword contains latest CRC
+        R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].ERFL = 0;
+
+        /* Dummy read to ensure that interrupt event is cleared. */
+        volatile uint32_t dummy = R_CANFD->CFDC[p_instance_ctrl->p_cfg->channel].ERFL;
+        FSP_PARAMETER_NOT_USED(dummy);
+
+        /* Choose the channel provided by the interrupt context. */
+        p_callback_ctrl = p_instance_ctrl;
+
+        args.channel   = p_instance_ctrl->p_cfg->channel;
+        args.p_context = p_instance_ctrl->p_context;
+        args.buffer    = 0U;
+    }
+
+    /* Set remaining arguments and call callback */
+    r_canfd_call_callback(p_callback_ctrl, &args);
+
+    /* Restore context if RTOS is used */
+    FSP_CONTEXT_RESTORE;
+
+    CANFD_CFG_MULTIPLEX_INTERRUPT_DISABLE;
+}
+
+/*******************************************************************************************************************//**
+ * Receive ISR.
+ *
+ * Saves context if RTOS is used, clears interrupts, calls common receive function
+ * and restores context if RTOS is used.
+ **********************************************************************************************************************/
+void canfd_rx_fifo_isr (void)
+{
+    CANFD_CFG_MULTIPLEX_INTERRUPT_ENABLE;
+
+    /* Save context if RTOS is used */
+    FSP_CONTEXT_SAVE;
+
+    can_callback_args_t args;
+
+    /* Get lowest FIFO requesting interrupt */
+    uint32_t fifo = __CLZ(__RBIT(R_CANFD->CFDRFISTS));
+
+    /* Only perform ISR duties if a FIFO has requested it */
+    if (fifo < CANFD_PRV_RX_FIFO_MAX)
+    {
+        /* Set static arguments */
+        args.event  = CAN_EVENT_RX_COMPLETE;
+        args.buffer = fifo + CANFD_PRV_RXMB_MAX;
+
+        /* Read from the FIFO until it is empty */
+        while (!(R_CANFD->CFDFESTS & (1U << fifo)))
+        {
+            /* Get channel associated with the AFL entry */
+            args.channel = R_CANFD->CFDRF[fifo].FDSTS_b.RFIFL;
+
+            /* Read and index FIFO */
+            r_canfd_mb_read(fifo + CANFD_PRV_RXMB_MAX, &args.frame);
+
+            /* Set the remaining callback arguments */
+            args.p_context = gp_instance_ctrl[args.channel]->p_context;
+            r_canfd_call_callback(gp_instance_ctrl[args.channel], &args);
+        }
+
+        /* Clear RX FIFO Interrupt Flag */
+        R_CANFD->CFDRFSTS[fifo] &= ~R_CANFD_CFDRFSTS_RFIF_Msk;
+
+        /* Dummy read to ensure that interrupt event is cleared. */
+        volatile uint32_t dummy = R_CANFD->CFDRFSTS[fifo];
+        FSP_PARAMETER_NOT_USED(dummy);
+    }
+
+    /* Restore context if RTOS is used */
+    FSP_CONTEXT_RESTORE;
+
+    CANFD_CFG_MULTIPLEX_INTERRUPT_DISABLE;
+}
+
+/*******************************************************************************************************************//**
+ * Transmit ISR.
+ *
+ * Saves context if RTOS is used, clears interrupts, calls common transmit function
+ * and restores context if RTOS is used.
+ **********************************************************************************************************************/
+void canfd_channel_tx_isr (void)
+{
+    CANFD_CFG_MULTIPLEX_INTERRUPT_ENABLE;
+
+    /* Save context if RTOS is used */
+    FSP_CONTEXT_SAVE;
+
+    IRQn_Type               irq             = R_FSP_CurrentIrqGet();
+    canfd_instance_ctrl_t * p_instance_ctrl = (canfd_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
+    uint32_t                channel         = p_instance_ctrl->p_cfg->channel;
+
+    /* Set static arguments */
+    can_callback_args_t args;
+    args.channel   = channel;
+    args.p_context = p_instance_ctrl->p_context;
+
+    /* Check the byte of CFDGTINTSTS0 that corresponds to the interrupting channel */
+    uint32_t cfdgtintsts = *((uint8_t *) (&R_CANFD->CFDGTINTSTS0) + channel);
+    while (cfdgtintsts)
+    {
+        uint32_t            txmb;
+        volatile uint32_t * cfdtm_sts;
+
+        channel <<= 1;
+
+        /* Get relevant TX status register bank */
+        if (cfdgtintsts & R_CANFD_CFDGTINTSTS0_TSIF0_Msk)
+        {
+            cfdtm_sts  = (volatile uint32_t *) &R_CANFD->CFDTMTCSTS[channel];
+            args.event = CAN_EVENT_TX_COMPLETE;
+        }
+        else
+        {
+            cfdtm_sts  = (volatile uint32_t *) &R_CANFD->CFDTMTASTS[channel];
+            args.event = CAN_EVENT_TX_ABORTED;
+        }
+
+        channel >>= 1;
+
+        /* Calculate lowest TXMB with the specified event */
+        txmb = __CLZ(__RBIT(*cfdtm_sts));
+        txmb = (txmb < 16) ? txmb : __CLZ(__RBIT(*(cfdtm_sts + 1))) + CANFD_PRV_TXMB_OFFSET;
+
+        /* Clear TX complete/abort flags */
+        R_CANFD->CFDTMSTS_b[txmb + (CANFD_PRV_TXMB_CHANNEL_OFFSET * channel)].TMTRF = 0;
+
+        /* Dummy read to ensure that interrupt event is cleared. */
+        volatile uint32_t dummy = R_CANFD->CFDTMSTS[txmb + (CANFD_PRV_TXMB_CHANNEL_OFFSET * channel)];
+        FSP_PARAMETER_NOT_USED(dummy);
+
+        /* Set the callback arguments */
+        args.buffer = txmb;
+        r_canfd_call_callback(p_instance_ctrl, &args);
+
+        /* Check for more interrupts on this channel */
+        cfdgtintsts = *((uint8_t *) (&R_CANFD->CFDGTINTSTS0) + channel);
+    }
+
+    /* Restore context if RTOS is used */
+    FSP_CONTEXT_RESTORE;
+
+    CANFD_CFG_MULTIPLEX_INTERRUPT_DISABLE;
+}
+
+/*******************************************************************************************************************//**
+ * This function is used to switch the CANFD peripheral operation mode.
+ * @param[in]  p_instance_ctrl   - pointer to control structure
+ * @param[in]  operation_mode    - destination operation mode
+ **********************************************************************************************************************/
+static void r_canfd_mode_transition (canfd_instance_ctrl_t * p_instance_ctrl, can_operation_mode_t operation_mode)
+{
+    uint32_t channel = p_instance_ctrl->p_cfg->channel;
+
+    /* Get bit 7 from operation_mode to determine if this is a global mode change request */
+    bool global_mode = (bool) (operation_mode >> 7);
+    operation_mode &= 0xF;
+
+    if (global_mode)
+    {
+        uint32_t cfdgctr = R_CANFD->CFDGCTR;
+
+        r_canfd_mode_ctr_set(&R_CANFD->CFDGCTR, operation_mode);
+
+        /* If CANFD is transitioning out of Reset the FIFOs need to be enabled. */
+        if ((cfdgctr & R_CANFD_CFDGSTS_GRSTSTS_Msk) && !(operation_mode & CAN_OPERATION_MODE_RESET))
+        {
+            /* Get global config */
+            canfd_global_cfg_t * p_global_cfg =
+                ((canfd_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend)->p_global_cfg;
+
+            /* Enable RX FIFOs */
+            for (uint32_t i = 0; i < CANFD_PRV_RX_FIFO_MAX; i++)
+            {
+                R_CANFD->CFDRFCC[i] = p_global_cfg->rx_fifo_config[i];
+            }
+        }
+    }
+    else
+    {
+        uint32_t cfdcnctr = R_CANFD->CFDC[channel].CTR;
+
+        if (((cfdcnctr & R_CANFD_CFDC_CTR_CSLPR_Msk) && (!(CAN_OPERATION_MODE_RESET & operation_mode))) ||
+            ((!(cfdcnctr & CANFD_PRV_CTR_RESET_BIT)) && (CAN_OPERATION_MODE_SLEEP == operation_mode)))
+        {
+            /* Transition channel to Reset if a transition to/from Sleep is requested (see Section "Channel
+             * Modes" in the RZ microprocessor User's Manual for details) */
+            r_canfd_mode_ctr_set(&R_CANFD->CFDC[channel].CTR, CAN_OPERATION_MODE_RESET);
+        }
+
+        /* Request transition to selected mode */
+        r_canfd_mode_ctr_set(&R_CANFD->CFDC[channel].CTR, operation_mode);
+    }
+
+    p_instance_ctrl->operation_mode = (can_operation_mode_t) (R_CANFD->CFDC[channel].CTR & CANFD_PRV_CTR_MODE_MASK);
+}
+
+/*******************************************************************************************************************//**
+ * Sets the provided CTR register to the requested mode and waits for the associated STS register to reflect the change
+ * @param[in]  p_ctr_reg            - pointer to control register
+ * @param[in]  operation_mode       - requested mode (not including global bits)
+ **********************************************************************************************************************/
+static void r_canfd_mode_ctr_set (volatile uint32_t * p_ctr_reg, can_operation_mode_t operation_mode)
+{
+    volatile uint32_t * p_sts_reg = p_ctr_reg + 1;
+
+    /* See definitions for CFDCnCTR, CFDCnSTS, CFDGCTR and CFDGSTS in the RZ microprocessor User's Manual */
+    *p_ctr_reg = (*p_ctr_reg & ~CANFD_PRV_CTR_MODE_MASK) | operation_mode;
+    FSP_HARDWARE_REGISTER_WAIT((*p_sts_reg & CANFD_PRV_CTR_MODE_MASK), operation_mode);
+}
+
+/*******************************************************************************************************************//**
+ * Converts bytes into a DLC value
+ * @param[in]  bytes       Number of payload bytes
+ **********************************************************************************************************************/
+static uint8_t r_canfd_bytes_to_dlc (uint8_t bytes)
+{
+    if (bytes <= 8)
+    {
+        return bytes;
+    }
+
+    if (bytes <= 24)
+    {
+        return (uint8_t) (8U + ((bytes - 8U) / 4U));
+    }
+
+    return (uint8_t) (0xDU + ((bytes / 16U) - 2U));
+}

+ 1601 - 0
projects/etherkit_ethercat_coe/rzn/fsp/src/r_gpt/r_gpt.c

@@ -0,0 +1,1601 @@
+/***********************************************************************************************************************
+ * Copyright [2020-2024] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
+ *
+ * This software and documentation are supplied by Renesas Electronics Corporation and/or its affiliates and may only
+ * be used with products of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.
+ * Renesas products are sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for
+ * the selection and use of Renesas products and Renesas assumes no liability.  No license, express or implied, to any
+ * intellectual property right is granted by Renesas.  This software is protected under all applicable laws, including
+ * copyright laws. Renesas reserves the right to change or discontinue this software and/or this documentation.
+ * THE SOFTWARE AND DOCUMENTATION IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND
+ * TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY,
+ * INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE
+ * SOFTWARE OR DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR
+ * DOCUMENTATION (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER,
+ * INCLUDING, WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY
+ * LOST PROFITS, OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+#include "r_gpt.h"
+#include "r_gpt_cfg.h"
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+
+/* "GPT" in ASCII, used to determine if channel is open. */
+#define GPT_OPEN                                         (0x00475054ULL)
+
+#define GPT_PRV_GTWP_RESET_VALUE                         (0xA500U)
+#define GPT_PRV_GTWP_WRITE_PROTECT                       (0xA51FU)
+
+#define GPT_PRV_GTIOR_STOP_LEVEL_BIT                     (6)
+#define GPT_PRV_GTIOR_INITIAL_LEVEL_BIT                  (4)
+
+#define GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END    (0x6U)
+#define GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END    (0x9U)
+
+#define GPT_PRV_GTIO_TOGGLE_COMPARE_MATCH                (0x3U)
+
+#define GPT_PRV_GTBER_BUFFER_ENABLE_FORCE_TRANSFER       (0x550000U)
+
+#define GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE             (0x80000000U)
+
+#define GPT_PRV_GTCCRA                                   (0U)
+#define GPT_PRV_GTCCRB                                   (1U)
+#define GPT_PRV_GTCCRC                                   (2U)
+#define GPT_PRV_GTCCRE                                   (3U)
+#define GPT_PRV_GTCCRD                                   (4U)
+#define GPT_PRV_GTCCRF                                   (5U)
+
+/* GPT_CFG_OUTPUT_SUPPORT_ENABLE is set to 2 to enable extra features. */
+#define GPT_PRV_EXTRA_FEATURES_ENABLED                   (2U)
+
+/***********************************************************************************************************************
+ * Typedef definitions
+ **********************************************************************************************************************/
+
+/* Duty cycle mode. */
+typedef enum e_gpt_duty_cycle_mode
+{
+    GPT_DUTY_CYCLE_MODE_REGISTER    = 0, // Duty cycle depends on compare match
+    GPT_DUTY_CYCLE_MODE_0_PERCENT   = 2, // Output low
+    GPT_DUTY_CYCLE_MODE_100_PERCENT = 3, // Output high
+} gpt_duty_cycle_mode_t;
+
+/* Count direction */
+typedef enum e_gpt_dir
+{
+    GPT_DIR_COUNT_DOWN = 0,
+    GPT_DIR_COUNT_UP   = 1
+} gpt_dir_t;
+
+typedef struct st_gpt_prv_duty_registers
+{
+    uint32_t gtccr_buffer;
+    uint32_t omdty;
+} gpt_prv_duty_registers_t;
+
+typedef enum e_gpt_prv_capture_event
+{
+    GPT_PRV_CAPTURE_EVENT_A,
+    GPT_PRV_CAPTURE_EVENT_B,
+} gpt_prv_capture_event_t;
+
+/***********************************************************************************************************************
+ * Private function prototypes
+ **********************************************************************************************************************/
+static void      gpt_counter_initialize(gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg);
+static fsp_err_t r_gpt_open_cfg_check(timer_cfg_t const * const p_cfg);
+static void      gpt_hardware_initialize(gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg);
+
+static void gpt_common_open(gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg);
+
+static uint32_t gpt_clock_frequency_get(gpt_instance_ctrl_t * const p_instance_ctrl);
+
+static void gpt_hardware_events_disable(gpt_instance_ctrl_t * p_instance_ctrl);
+
+static void r_gpt_disable_irq(IRQn_Type irq);
+static void gpt_disable_interrupt(gpt_instance_ctrl_t * const p_instance_ctrl);
+
+static inline void r_gpt_write_protect_enable(gpt_instance_ctrl_t * const p_instance_ctrl);
+static inline void r_gpt_write_protect_disable(gpt_instance_ctrl_t * const p_instance_ctrl);
+
+/* Noinline attribute added to reduce code size for CM23 GCC build. */
+static void r_gpt_enable_irq(IRQn_Type const irq, uint32_t priority, void * p_context) __attribute__((noinline));
+static void gpt_enable_interrupt(gpt_instance_ctrl_t * const p_instance_ctrl);
+
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+static void gpt_calculate_duty_cycle(gpt_instance_ctrl_t * const p_instance_ctrl,
+                                     uint32_t const              duty_cycle_counts,
+                                     gpt_prv_duty_registers_t  * p_duty_reg);
+
+static uint32_t gpt_gtior_calculate(timer_cfg_t const * const p_cfg, gpt_pin_level_t const stop_level);
+
+#endif
+
+static void r_gpt_call_callback(gpt_instance_ctrl_t * p_ctrl, timer_event_t event, uint32_t capture);
+
+/***********************************************************************************************************************
+ * ISR prototypes
+ **********************************************************************************************************************/
+void gpt_counter_overflow_isr(void);
+void gpt_counter_underflow_isr(void);
+void gpt_dead_time_isr(void);
+void gpt_capture_a_isr(void);
+void gpt_capture_b_isr(void);
+
+/***********************************************************************************************************************
+ * Private global variables
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Global Variables
+ **********************************************************************************************************************/
+
+/* GPT implementation of timer interface  */
+const timer_api_t g_timer_on_gpt =
+{
+    .open         = R_GPT_Open,
+    .stop         = R_GPT_Stop,
+    .start        = R_GPT_Start,
+    .reset        = R_GPT_Reset,
+    .enable       = R_GPT_Enable,
+    .disable      = R_GPT_Disable,
+    .periodSet    = R_GPT_PeriodSet,
+    .dutyCycleSet = R_GPT_DutyCycleSet,
+    .infoGet      = R_GPT_InfoGet,
+    .statusGet    = R_GPT_StatusGet,
+    .callbackSet  = R_GPT_CallbackSet,
+    .close        = R_GPT_Close,
+};
+
+/*******************************************************************************************************************//**
+ * @addtogroup GPT
+ * @{
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Functions
+ **********************************************************************************************************************/
+
+/*******************************************************************************************************************//**
+ * Initializes the timer module and applies configurations. Implements @ref timer_api_t::open.
+ *
+ * GPT hardware does not support one-shot functionality natively.  When using one-shot mode, the timer will be stopped
+ * in an ISR after the requested period has elapsed.
+ *
+ * The GPT implementation of the general timer can accept a gpt_extended_cfg_t extension parameter.
+ *
+ * @retval FSP_SUCCESS                    Initialization was successful and timer has started.
+ * @retval FSP_ERR_ASSERTION              A required input pointer is NULL or the source divider is invalid.
+ * @retval FSP_ERR_ALREADY_OPEN           Module is already open.
+ * @retval FSP_ERR_IRQ_BSP_DISABLED       timer_cfg_t::mode is ::TIMER_MODE_ONE_SHOT or timer_cfg_t::p_callback is not
+ *                                        NULL, but ISR is not enabled.  ISR must be enabled to use one-shot mode or
+ *                                        callback.
+ * @retval FSP_ERR_INVALID_MODE           Triangle wave PWM is only supported if GPT_CFG_OUTPUT_SUPPORT_ENABLE is 2.
+ * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The channel requested in the p_cfg parameter is not available on this device.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Open (timer_ctrl_t * const p_ctrl, timer_cfg_t const * const p_cfg)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_cfg);
+    FSP_ASSERT(NULL != p_cfg->p_extend);
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ASSERT((p_cfg->source_div != 7U) && (p_cfg->source_div != 9U) && (p_cfg->source_div <= 10));
+ #if GPT_PRV_EXTRA_FEATURES_ENABLED != GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    FSP_ERROR_RETURN(p_cfg->mode <= TIMER_MODE_PWM, FSP_ERR_INVALID_MODE);
+ #endif
+    FSP_ERROR_RETURN(GPT_OPEN != p_instance_ctrl->open, FSP_ERR_ALREADY_OPEN);
+#endif
+
+    /** mask_bit GPTunit0 0-6bit, GPTunit1 0-6bit, GPTunit2 0-3bit*/
+    if (p_cfg->channel <= GPT_CHANNEL_UNIT0_6)
+    {
+        p_instance_ctrl->channel_mask = (1U << p_cfg->channel);
+    }
+    else if ((GPT_CHANNEL_UNIT1_0 <= p_cfg->channel) && (p_cfg->channel <= GPT_CHANNEL_UNIT1_6))
+    {
+        p_instance_ctrl->channel_mask = (1U << (p_cfg->channel - GPT_CHANNEL_UNIT1_0));
+    }
+    else
+    {
+        p_instance_ctrl->channel_mask = (1U << (p_cfg->channel - GPT_CHANNEL_UNIT2_0));
+    }
+
+    /* Verify the configuration parameters are valid   */
+    fsp_err_t err = r_gpt_open_cfg_check(p_cfg);
+    FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
+
+    /* Initialize control structure based on configurations. */
+    gpt_common_open(p_instance_ctrl, p_cfg);
+
+    gpt_hardware_initialize(p_instance_ctrl, p_cfg);
+
+    p_instance_ctrl->open = GPT_OPEN;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Stops timer. Implements @ref timer_api_t::stop.
+ *
+ * @retval FSP_SUCCESS                 Timer successfully stopped.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Stop (timer_ctrl_t * const p_ctrl)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Stop timer */
+    p_instance_ctrl->p_reg->GTSTP = p_instance_ctrl->channel_mask;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Starts timer. Implements @ref timer_api_t::start.
+ *
+ * @retval FSP_SUCCESS                 Timer successfully started.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Start (timer_ctrl_t * const p_ctrl)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Start timer */
+    p_instance_ctrl->p_reg->GTSTR = p_instance_ctrl->channel_mask;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Resets the counter value to 0. Implements @ref timer_api_t::reset.
+ *
+ * @note This function also updates to the new period if no counter overflow has occurred since the last call to
+ * R_GPT_PeriodSet().
+ *
+ * @retval FSP_SUCCESS                 Counter value written successfully.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Reset (timer_ctrl_t * const p_ctrl)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Clear timer counter. */
+    p_instance_ctrl->p_reg->GTCLR = p_instance_ctrl->channel_mask;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Enables external event triggers that start, stop, clear, or capture the counter. Implements @ref timer_api_t::enable.
+ *
+ * @retval FSP_SUCCESS                 External events successfully enabled.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Enable (timer_ctrl_t * const p_ctrl)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Enable use of GTSTR, GTSTP, and GTCLR for this channel. */
+    gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
+    uint32_t             gtssr    = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
+    uint32_t             gtpsr    = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
+    uint32_t             gtcsr    = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
+
+    /* OR with user settings. */
+    gtssr |= p_extend->start_source;
+    gtpsr |= p_extend->stop_source;
+    gtcsr |= p_extend->clear_source;
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    /* Set the count sources. Ensure stop and clear sources are set before start source, and capture sources are set
+     * after start source. */
+    p_instance_ctrl->p_reg->GTPSR   = gtpsr;
+    p_instance_ctrl->p_reg->GTCSR   = gtcsr;
+    p_instance_ctrl->p_reg->GTSSR   = gtssr;
+    p_instance_ctrl->p_reg->GTICASR = p_extend->capture_a_source;
+    p_instance_ctrl->p_reg->GTICBSR = p_extend->capture_b_source;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Disables external event triggers that start, stop, clear, or capture the counter. Implements @ref timer_api_t::disable.
+ *
+ * @note The timer could be running after R_GPT_Disable(). To ensure it is stopped, call R_GPT_Stop().
+ *
+ * @retval FSP_SUCCESS                 External events successfully disabled.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Disable (timer_ctrl_t * const p_ctrl)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    gpt_hardware_events_disable(p_instance_ctrl);
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Sets period value provided. If the timer is running, the period will be updated after the next counter overflow.
+ * If the timer is stopped, this function resets the counter and updates the period.
+ * Implements @ref timer_api_t::periodSet.
+ *
+ * @warning If periodic output is used, the duty cycle buffer registers are updated after the period buffer register.
+ * If this function is called while the timer is running and a GPT overflow occurs during processing, the duty cycle
+ * will not be the desired 50% duty cycle until the counter overflow after processing completes.
+ *
+ * @retval FSP_SUCCESS                 Period value written successfully.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_PeriodSet (timer_ctrl_t * const p_ctrl, uint32_t const period_counts)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    /* Update period buffer register. The actual period is one cycle longer than the register value for saw waves
+     * and twice the register value for triangle waves. Reference section 19.2.21 "General PWM Timer Cycle Setting
+     * Register (GTPR)". The setting passed to the configuration is expected to be half the desired period for
+     * triangle waves. */
+    uint32_t new_gtpr = period_counts - 1U;
+#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    if (p_instance_ctrl->p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
+    {
+        new_gtpr = period_counts;
+    }
+#endif
+
+    p_instance_ctrl->p_reg->GTPBR = new_gtpr;
+
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+    /* Set a 50% duty cycle so the period of the waveform on the output pin matches the requested period. */
+    if (TIMER_MODE_PERIODIC == p_instance_ctrl->p_cfg->mode)
+    {
+        /* The  GTIOCA/GTIOCB pins transition 1 cycle after compare match when buffer operation is used (see
+         * Section "PWM Output Operating Mode" in the RZ microprocessor User's Manual for details). To get a duty cycle
+         * as close to 50% as possible, duty cycle (register) = (period (counts) / 2) - 1. */
+        uint32_t duty_cycle_50_percent = (period_counts >> 1) - 1U;
+        p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRC] = duty_cycle_50_percent;
+        p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRE] = duty_cycle_50_percent;
+    }
+#endif
+
+    /* If the counter is not counting, update period register and reset counter. */
+    if (0U == p_instance_ctrl->p_reg->GTCR_b.CST)
+    {
+        p_instance_ctrl->p_reg->GTPR = new_gtpr;
+
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+        p_instance_ctrl->p_reg->GTBER = GPT_PRV_GTBER_BUFFER_ENABLE_FORCE_TRANSFER;
+#endif
+
+        p_instance_ctrl->p_reg->GTCLR = p_instance_ctrl->channel_mask;
+    }
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Sets duty cycle on requested pin. Implements @ref timer_api_t::dutyCycleSet.
+ *
+ * Duty cycle is updated in the buffer register. The updated duty cycle is reflected after the next cycle end (counter
+ * overflow).
+ *
+ * @param[in] p_ctrl                   Pointer to instance control block.
+ * @param[in] duty_cycle_counts        Duty cycle to set in counts.
+ * @param[in] pin                      Use gpt_io_pin_t to select GPT_IO_PIN_GTIOCA or GPT_IO_PIN_GTIOCB
+ *
+ * @retval FSP_SUCCESS                 Duty cycle updated successfully.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL or the pin is not one of gpt_io_pin_t
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ * @retval FSP_ERR_INVALID_ARGUMENT    Duty cycle is larger than period.
+ * @retval FSP_ERR_UNSUPPORTED         GPT_CFG_OUTPUT_SUPPORT_ENABLE is 0.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_DutyCycleSet (timer_ctrl_t * const p_ctrl, uint32_t const duty_cycle_counts, uint32_t const pin)
+{
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+ #if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ASSERT(pin <= GPT_IO_PIN_GTIOCA_AND_GTIOCB);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+    FSP_ERROR_RETURN(duty_cycle_counts <= (p_instance_ctrl->p_reg->GTPR + 1), FSP_ERR_INVALID_ARGUMENT);
+ #endif
+
+    /* Set duty cycle. */
+    gpt_prv_duty_registers_t duty_regs = {UINT32_MAX, 0};
+    gpt_calculate_duty_cycle(p_instance_ctrl, duty_cycle_counts, &duty_regs);
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    switch (pin + GPT_PRV_GTCCRC)
+    {
+        case GPT_PRV_GTCCRC:
+        {
+            p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRC] = duty_regs.gtccr_buffer;
+            break;
+        }
+
+        case GPT_PRV_GTCCRE:
+        {
+            p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRE] = duty_regs.gtccr_buffer;
+            break;
+        }
+
+        case GPT_PRV_GTCCRD:
+        {
+            p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRD] = duty_regs.gtccr_buffer;
+            break;
+        }
+
+        case GPT_PRV_GTCCRF:
+        {
+            p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRF] = duty_regs.gtccr_buffer;
+            break;
+        }
+
+        default:
+        {
+            break;
+        }
+    }
+
+    /* Read modify write bitfield access is used to update GTUDDTYC to make sure we don't clobber settings for the
+     * other pin. */
+
+    uint32_t gtuddtyc = p_instance_ctrl->p_reg->GTUDDTYC;
+    if (GPT_IO_PIN_GTIOCB != pin)
+    {
+        /* GTIOCA or both GTIOCA and GTIOCB. */
+        gtuddtyc &= ~R_GPT7_GTUDDTYC_OADTY_Msk;
+        gtuddtyc |= duty_regs.omdty << R_GPT7_GTUDDTYC_OADTY_Pos;
+    }
+
+    if (GPT_IO_PIN_GTIOCA != pin)
+    {
+        /* GTIOCB or both GTIOCA and GTIOCB. */
+        gtuddtyc &= ~R_GPT7_GTUDDTYC_OBDTY_Msk;
+        gtuddtyc |= duty_regs.omdty << R_GPT7_GTUDDTYC_OBDTY_Pos;
+    }
+
+    p_instance_ctrl->p_reg->GTUDDTYC = gtuddtyc;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+#else
+    FSP_PARAMETER_NOT_USED(p_ctrl);
+    FSP_PARAMETER_NOT_USED(duty_cycle_counts);
+    FSP_PARAMETER_NOT_USED(pin);
+
+    FSP_RETURN(FSP_ERR_UNSUPPORTED);
+#endif
+}
+
+/*******************************************************************************************************************//**
+ * Get timer information and store it in provided pointer p_info. Implements @ref timer_api_t::infoGet.
+ *
+ * @retval FSP_SUCCESS                 Period, count direction, frequency, and ELC event written to caller's
+ *                                     structure successfully.(External clock(GTETRGA - GTETRGD) cannot be acquired.)
+ * @retval FSP_ERR_ASSERTION           p_ctrl or p_info was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_InfoGet (timer_ctrl_t * const p_ctrl, timer_info_t * const p_info)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ASSERT(NULL != p_info);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Get and store period */
+    uint32_t gtpr          = p_instance_ctrl->p_reg->GTPR;
+    uint32_t period_counts = gtpr + 1;
+#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    if (p_instance_ctrl->p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
+    {
+        period_counts = gtpr;
+    }
+#endif
+    p_info->period_counts = period_counts;
+
+    /* Get and store clock frequency */
+    p_info->clock_frequency = gpt_clock_frequency_get(p_instance_ctrl);
+
+    /* Get and store clock counting direction. Read count direction setting */
+    p_info->count_direction = TIMER_DIRECTION_UP;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Get current timer status and store it in provided pointer p_status. Implements @ref timer_api_t::statusGet.
+ *
+ * @retval FSP_SUCCESS                 Current timer state and counter value set successfully.
+ * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_StatusGet (timer_ctrl_t * const p_ctrl, timer_status_t * const p_status)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ASSERT(NULL != p_status);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Get counter state. */
+    p_status->state = (timer_state_t) p_instance_ctrl->p_reg->GTCR_b.CST;
+
+    /* Get counter value */
+    p_status->counter = p_instance_ctrl->p_reg->GTCNT;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Set counter value.
+ *
+ * @note Do not call this API while the counter is counting.  The counter value can only be updated while the counter
+ * is stopped.
+ *
+ * @retval FSP_SUCCESS                 Counter value updated.
+ * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ * @retval FSP_ERR_IN_USE              The timer is running.  Stop the timer before calling this function.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_CounterSet (timer_ctrl_t * const p_ctrl, uint32_t counter)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+    FSP_ERROR_RETURN(0U == p_instance_ctrl->p_reg->GTCR_b.CST, FSP_ERR_IN_USE);
+#endif
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    /* Set counter value */
+    p_instance_ctrl->p_reg->GTCNT = counter;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Enable output for GTIOCA and/or GTIOCB.
+ *
+ * @retval FSP_SUCCESS                 Output is enabled.
+ * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_OutputEnable (timer_ctrl_t * const p_ctrl, gpt_io_pin_t pin)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    uint32_t gtior = p_instance_ctrl->p_reg->GTIOR;
+    if (GPT_IO_PIN_GTIOCB != pin)
+    {
+        /* GTIOCA or both GTIOCA and GTIOCB. */
+        gtior |= R_GPT7_GTIOR_OAE_Msk;
+    }
+
+    if (GPT_IO_PIN_GTIOCA != pin)
+    {
+        /* GTIOCB or both GTIOCA and GTIOCB. */
+        gtior |= R_GPT7_GTIOR_OBE_Msk;
+    }
+
+    p_instance_ctrl->p_reg->GTIOR = gtior;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Disable output for GTIOCA and/or GTIOCB.
+ *
+ * @retval FSP_SUCCESS                 Output is disabled.
+ * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_OutputDisable (timer_ctrl_t * const p_ctrl, gpt_io_pin_t pin)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    uint32_t gtior = p_instance_ctrl->p_reg->GTIOR;
+    if (GPT_IO_PIN_GTIOCB != pin)
+    {
+        /* GTIOCA or both GTIOCA and GTIOCB. */
+        gtior &= ~R_GPT7_GTIOR_OAE_Msk;
+    }
+
+    if (GPT_IO_PIN_GTIOCA != pin)
+    {
+        /* GTIOCB or both GTIOCA and GTIOCB. */
+        gtior &= ~R_GPT7_GTIOR_OBE_Msk;
+    }
+
+    p_instance_ctrl->p_reg->GTIOR = gtior;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Set A/D converter start request compare match value.
+ *
+ * @retval FSP_SUCCESS                 Counter value updated.
+ * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_AdcTriggerSet (timer_ctrl_t * const    p_ctrl,
+                               gpt_adc_compare_match_t which_compare_match,
+                               uint32_t                compare_match_value)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+    FSP_ASSERT(p_instance_ctrl->p_cfg->channel < BSP_FEATURE_GPT_SAFETY_BASE_CHANNEL);
+#endif
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    /* Set A/D converter start request compare match value. */
+    volatile uint32_t * p_gtadtr = &p_instance_ctrl->p_reg->GTADTRA;
+    p_gtadtr[which_compare_match] = compare_match_value;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Updates the user callback with the option to provide memory for the callback argument structure.
+ * Implements @ref timer_api_t::callbackSet.
+ *
+ * @retval  FSP_SUCCESS                  Callback updated successfully.
+ * @retval  FSP_ERR_ASSERTION            A required pointer is NULL.
+ * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_CallbackSet (timer_ctrl_t * const          p_ctrl,
+                             void (                      * p_callback)(timer_callback_args_t *),
+                             void const * const            p_context,
+                             timer_callback_args_t * const p_callback_memory)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(p_instance_ctrl);
+    FSP_ASSERT(p_callback);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Store callback and context */
+    p_instance_ctrl->p_callback        = p_callback;
+    p_instance_ctrl->p_context         = p_context;
+    p_instance_ctrl->p_callback_memory = p_callback_memory;
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Stops counter, disables output pins, and clears internal driver data. Implements @ref timer_api_t::close.
+ *
+ * @retval FSP_SUCCESS                 Successful close.
+ * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
+ * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_GPT_Close (timer_ctrl_t * const p_ctrl)
+{
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
+    fsp_err_t             err             = FSP_SUCCESS;
+
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ASSERT(NULL != p_instance_ctrl);
+    FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+    /* Clear open flag. */
+    p_instance_ctrl->open = 0U;
+
+    r_gpt_write_protect_disable(p_instance_ctrl);
+
+    /* Stop counter. */
+    p_instance_ctrl->p_reg->GTSTP = p_instance_ctrl->channel_mask;
+
+    /* Disable output. */
+    p_instance_ctrl->p_reg->GTIOR = 0U;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    /* Disable interrupts. */
+    gpt_disable_interrupt(p_instance_ctrl);
+
+    return err;
+}
+
+/** @} (end addtogroup GPT) */
+
+/*******************************************************************************************************************//**
+ * Private Functions
+ **********************************************************************************************************************/
+
+/*******************************************************************************************************************//**
+ * Enables write protection.
+ *
+ * @param[in]  p_instance_ctrl         Instance control block.
+ **********************************************************************************************************************/
+static inline void r_gpt_write_protect_enable (gpt_instance_ctrl_t * const p_instance_ctrl)
+{
+#if GPT_CFG_WRITE_PROTECT_ENABLE
+    p_instance_ctrl->p_reg->GTWP = GPT_PRV_GTWP_WRITE_PROTECT;
+#else
+    FSP_PARAMETER_NOT_USED(p_instance_ctrl);
+#endif
+}
+
+/*******************************************************************************************************************//**
+ * Disables write protection.
+ *
+ * @param[in]  p_instance_ctrl         Instance control block.
+ **********************************************************************************************************************/
+static inline void r_gpt_write_protect_disable (gpt_instance_ctrl_t * const p_instance_ctrl)
+{
+#if GPT_CFG_WRITE_PROTECT_ENABLE
+    p_instance_ctrl->p_reg->GTWP = GPT_PRV_GTWP_RESET_VALUE;
+#else
+    FSP_PARAMETER_NOT_USED(p_instance_ctrl);
+#endif
+}
+
+/*******************************************************************************************************************//**
+ * Validates the configuration arguments for illegal combinations or options.
+ *
+ * @param[in]  p_cfg                      Pointer to timer configuration.
+ *
+ * @retval FSP_SUCCESS                    No configuration errors detected
+ * @retval FSP_ERR_ASSERTION              An input argument is invalid.
+ * @retval FSP_ERR_IRQ_BSP_DISABLED       timer_cfg_t::mode is ::TIMER_MODE_ONE_SHOT or timer_cfg_t::p_callback is not
+ *                                        NULL, but ISR is not enabled.  ISR must be enabled to use one-shot mode or
+ *                                        callback.
+ * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The channel requested in the p_cfg parameter is not available on this device.
+ **********************************************************************************************************************/
+static fsp_err_t r_gpt_open_cfg_check (timer_cfg_t const * const p_cfg)
+{
+#if GPT_CFG_PARAM_CHECKING_ENABLE
+    FSP_ERROR_RETURN((p_cfg->channel <= GPT_CHANNEL_UNIT2_3), FSP_ERR_IP_CHANNEL_NOT_PRESENT);
+
+    if ((p_cfg->p_callback) || (TIMER_MODE_ONE_SHOT == p_cfg->mode))
+    {
+        FSP_ERROR_RETURN(p_cfg->cycle_end_irq >= 0, FSP_ERR_IRQ_BSP_DISABLED);
+    }
+
+ #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+    /* Callback is required if underflow interrupt is enabled. */
+    gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_cfg->p_extend;
+
+    gpt_extended_pwm_cfg_t const * p_pwm_cfg = p_extend->p_pwm_cfg;
+    if (NULL != p_pwm_cfg)
+    {
+        if (p_pwm_cfg->trough_irq >= 0)
+        {
+            FSP_ASSERT(NULL != p_cfg->p_callback);
+        }
+    }
+ #endif
+#else
+    FSP_PARAMETER_NOT_USED(p_cfg);
+#endif
+
+    return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Initializes control structure based on configuration.
+ *
+ * @param[in]  p_instance_ctrl         Instance control block.
+ * @param[in]  p_cfg                   Pointer to timer configuration.
+ **********************************************************************************************************************/
+static void gpt_common_open (gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg)
+{
+    /* Initialize control structure.  */
+    p_instance_ctrl->p_cfg = p_cfg;
+
+    /* If callback is not null or timer mode is one shot, make sure the IRQ is enabled and store callback in the
+     *  control block.
+     *  @note The GPT hardware does not support one-shot mode natively.  To support one-shot mode, the timer will be
+     *  stopped and cleared using software in the ISR. *//* Determine if this is a 32-bit or a 16-bit timer. */
+    p_instance_ctrl->variant = TIMER_VARIANT_16_BIT;
+    if (0U != (p_instance_ctrl->channel_mask & BSP_FEATURE_GPT_32BIT_CHANNEL_MASK))
+    {
+        p_instance_ctrl->variant = TIMER_VARIANT_32_BIT;
+    }
+
+    /* Save register base address. */
+    uint32_t base_address;
+    if (p_cfg->channel <= GPT_CHANNEL_UNIT0_6)
+    {
+        base_address = (uint32_t) R_GPT0 + ((uint32_t) p_cfg->channel * ((uint32_t) R_GPT1 - (uint32_t) R_GPT0));
+    }
+    else if ((GPT_CHANNEL_UNIT1_0 <= p_cfg->channel) && (p_cfg->channel <= GPT_CHANNEL_UNIT1_6))
+    {
+        base_address = (uint32_t) R_GPT7 +
+                       (((uint32_t) p_cfg->channel - GPT_CHANNEL_UNIT1_0) * ((uint32_t) R_GPT8 - (uint32_t) R_GPT7));
+    }
+    else
+    {
+        base_address = (uint32_t) R_GPT14 +
+                       (((uint32_t) p_cfg->channel - GPT_CHANNEL_UNIT2_0) * ((uint32_t) R_GPT15 - (uint32_t) R_GPT14));
+    }
+
+    p_instance_ctrl->p_reg = (R_GPT0_Type *) base_address;
+
+    /* Set callback and context pointers, if configured */
+    p_instance_ctrl->p_callback        = p_cfg->p_callback;
+    p_instance_ctrl->p_context         = p_cfg->p_context;
+    p_instance_ctrl->p_callback_memory = NULL;
+}
+
+/*******************************************************************************************************************//**
+ * Performs hardware initialization of the GPT.
+ *
+ * @param[in]  p_instance_ctrl        Instance control block.
+ * @param[in]  p_cfg                  Pointer to timer configuration.
+ **********************************************************************************************************************/
+static void gpt_hardware_initialize (gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg)
+{
+    /* Save pointer to extended configuration structure. */
+    gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_cfg->p_extend;
+
+    /* Counter related initialization */
+    gpt_counter_initialize(p_instance_ctrl, p_cfg);
+
+    uint32_t gtuddtyc = 0U;
+    uint32_t gtior    = 0U;
+
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+    /* For one shot mode, the compare match buffer register must be loaded with a value that exceeds the timer
+     * cycle end value so that second compare match event would never occur and hence there will be only a
+     * single pulse.  Writing to the upper bits is ignored for 16-bit timers. */
+    gpt_prv_duty_registers_t duty_regs = {UINT32_MAX, 0};
+
+    if (TIMER_MODE_PERIODIC == p_cfg->mode)
+    {
+        /* The  GTIOCA/GTIOCB pins transition 1 cycle after compare match when buffer operation is used (see
+         * Section "PWM Output Operating Mode" in the RZ microprocessor User's Manual for details). To get a duty cycle
+         * as close to 50% as possible, duty cycle (register) = (period (counts) / 2) - 1. */
+        uint32_t duty_cycle_50_percent = (p_cfg->period_counts >> 1) - 1U;
+        duty_regs.gtccr_buffer = duty_cycle_50_percent;
+    }
+
+    if (p_cfg->mode >= TIMER_MODE_PWM)
+    {
+        gpt_calculate_duty_cycle(p_instance_ctrl, p_cfg->duty_cycle_counts, &duty_regs);
+    }
+
+    /* Set the compare match and compare match buffer registers based on previously calculated values. */
+    p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRC] = duty_regs.gtccr_buffer;
+    p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRE] = duty_regs.gtccr_buffer;
+
+    /* If the requested duty cycle is 0% or 100%, set this in the registers. */
+    gtuddtyc |= duty_regs.omdty << R_GPT7_GTUDDTYC_OADTY_Pos;
+    gtuddtyc |= duty_regs.omdty << R_GPT7_GTUDDTYC_OBDTY_Pos;
+
+    /* Calculate GTIOR. */
+    if (p_extend->gtioca.output_enabled)
+    {
+        uint32_t gtioca_gtior = gpt_gtior_calculate(p_cfg, p_extend->gtioca.stop_level);
+        gtior |= gtioca_gtior << R_GPT7_GTIOR_GTIOA_Pos;
+    }
+
+    if (p_extend->gtiocb.output_enabled)
+    {
+        uint32_t gtiocb_gtior = gpt_gtior_calculate(p_cfg, p_extend->gtiocb.stop_level);
+        gtior |= gtiocb_gtior << R_GPT7_GTIOR_GTIOB_Pos;
+    }
+#endif
+
+    /* It must be cleared before setting. When modifying the
+     * IVTT[2:0] bits, first set the IVTC[1:0] bits to 00b. */
+    p_instance_ctrl->p_reg->GTITC  = 0U;
+    p_instance_ctrl->p_reg->GTEITC = 0U;
+
+#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    gpt_extended_pwm_cfg_t const * p_pwm_cfg = p_extend->p_pwm_cfg;
+    if (NULL != p_pwm_cfg)
+    {
+        p_instance_ctrl->p_reg->GTINTAD = ((uint32_t) p_pwm_cfg->output_disable << R_GPT7_GTINTAD_GRPDTE_Pos) |
+                                          ((uint32_t) p_pwm_cfg->poeg_link << R_GPT7_GTINTAD_GRP_Pos) |
+                                          ((uint32_t) p_pwm_cfg->adc_trigger << R_GPT7_GTINTAD_ADTRAUEN_Pos);
+        p_instance_ctrl->p_reg->GTDVU = p_pwm_cfg->dead_time_count_up;
+
+        /* Set GTDTCR.TDE only if one of the dead time values is non-zero. */
+        uint32_t gtdtcr =
+            ((p_pwm_cfg->dead_time_count_up > 0) || (p_pwm_cfg->dead_time_count_down > 0));
+
+        p_instance_ctrl->p_reg->GTITC = ((uint32_t) p_pwm_cfg->interrupt_skip_source << R_GPT7_GTITC_IVTC_Pos) |
+                                        ((uint32_t) p_pwm_cfg->interrupt_skip_count << R_GPT7_GTITC_IVTT_Pos) |
+                                        ((uint32_t) p_pwm_cfg->interrupt_skip_adc << R_GPT7_GTITC_ADTAL_Pos);
+        p_instance_ctrl->p_reg->GTEITC =
+            ((uint32_t) p_pwm_cfg->interrupt_skip_source_ext1 << R_GPT7_GTEITC_EIVTC1_Pos) |
+            ((uint32_t) p_pwm_cfg->interrupt_skip_count_ext1 << R_GPT7_GTEITC_EIVTT1_Pos) |
+            ((uint32_t) p_pwm_cfg->interrupt_skip_source_ext2 <<
+                R_GPT7_GTEITC_EIVTC2_Pos) |
+            ((uint32_t) p_pwm_cfg->interrupt_skip_count_ext2 << R_GPT7_GTEITC_EIVTT2_Pos);
+        p_instance_ctrl->p_reg->GTEITLI1 =
+            ((uint32_t) p_pwm_cfg->interrupt_skip_func_ovf << R_GPT7_GTEITLI1_EITLV_Pos) |
+            ((uint32_t) p_pwm_cfg->interrupt_skip_func_unf << R_GPT7_GTEITLI1_EITLU_Pos);
+        p_instance_ctrl->p_reg->GTEITLI2 =
+            ((uint32_t) p_pwm_cfg->interrupt_skip_func_adc_a << R_GPT7_GTEITLI2_EADTAL_Pos) |
+            ((uint32_t) p_pwm_cfg->interrupt_skip_func_adc_b <<
+                R_GPT7_GTEITLI2_EADTBL_Pos);
+        p_instance_ctrl->p_reg->GTDVD = p_pwm_cfg->dead_time_count_down;
+
+        /* GADTRm does not exist in the SAFETY area, so it is not accessed. */
+        if (0 ==
+            ((1U << (p_cfg->channel)) & (BSP_FEATURE_GPT_SAFETY_CHANNEL_MASK << BSP_FEATURE_GPT_SAFETY_BASE_CHANNEL)))
+        {
+            p_instance_ctrl->p_reg->GTADTRA = p_pwm_cfg->adc_a_compare_match;
+            p_instance_ctrl->p_reg->GTADTRB = p_pwm_cfg->adc_b_compare_match;
+        }
+
+        /* If custom GTIOR settings are not provided, set gtioca_disable_settings and gtiocb_disable_settings. */
+        gtior |= (uint32_t) (p_pwm_cfg->gtioca_disable_setting << R_GPT7_GTIOR_OADF_Pos);
+        gtior |= (uint32_t) (p_pwm_cfg->gtiocb_disable_setting << R_GPT7_GTIOR_OBDF_Pos);
+
+        p_instance_ctrl->p_reg->GTDTCR = gtdtcr;
+    }
+    else
+#endif
+    {
+        /* GTADTR* registers are unused if GTINTAD is cleared. */
+        p_instance_ctrl->p_reg->GTINTAD = 0U;
+        p_instance_ctrl->p_reg->GTDTCR  = 0U;
+
+        /* GTDVU, GTDVD, GTDBU, GTDBD, and GTSOTR are not used if GTDTCR is cleared. */
+    }
+
+    /* Configure the noise filter for the GTIOC pins. */
+    gtior |= (uint32_t) (p_extend->capture_filter_gtioca << R_GPT7_GTIOR_NFAEN_Pos);
+    gtior |= (uint32_t) (p_extend->capture_filter_gtiocb << R_GPT7_GTIOR_NFBEN_Pos);
+
+    /* Enable the compare match buffer. */
+    p_instance_ctrl->p_reg->GTBER = GPT_PRV_GTBER_BUFFER_ENABLE_FORCE_TRANSFER;
+
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    if (TIMER_MODE_ONE_SHOT == p_cfg->mode)
+    {
+        /* In one shot mode, the output pin toggles when counting starts, then again when the period expires.
+         * The buffer is enabled to set the compare match to UINT32_MAX after the one shot pulse is output
+         * so that the pin level will not change if the period expires again before the timer is stopped in
+         * the interrupt.*/
+        p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRA] = 0U;
+        p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRB] = 0U;
+    }
+#endif
+
+    /* Reset counter to 0. */
+    p_instance_ctrl->p_reg->GTCLR = p_instance_ctrl->channel_mask;
+
+    /* Set the I/O control register. */
+    p_instance_ctrl->p_reg->GTIOR = gtior;
+
+    /* Configure duty cycle and force timer to count up. GTUDDTYC must be set, then cleared to force the count
+     * direction to be reflected when counting starts (see Section "General PWM Timer Count Direction
+     * and Duty Setting Register (GTUDDTYC)" in the RZ microprocessor User's Manual for details). */
+    p_instance_ctrl->p_reg->GTUDDTYC = gtuddtyc | 3U;
+    p_instance_ctrl->p_reg->GTUDDTYC = gtuddtyc | 1U;
+
+    r_gpt_write_protect_enable(p_instance_ctrl);
+
+    gpt_enable_interrupt(p_instance_ctrl);
+}
+
+/*******************************************************************************************************************//**
+ * Counter initialization of the GPT.
+ *
+ * @param[in]  p_instance_ctrl        Instance control block.
+ * @param[in]  p_cfg                  Pointer to timer configuration.
+ **********************************************************************************************************************/
+static void gpt_counter_initialize (gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg)
+{
+    gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_cfg->p_extend;
+
+    /* Power on GPT before setting any hardware registers. Make sure the counter is stopped before setting mode
+     * register, PCLK divisor register, and counter register. */
+    R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_LPC_RESET);
+    R_BSP_MODULE_START(FSP_IP_GPT, p_cfg->channel);
+    R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_LPC_RESET);
+
+    /* Initialize all registers that may affect operation of this driver to reset values.  Skip these since they
+     * affect all channels, and are initialized in GTCR and GTCNT: GTSTR, GTSTP, GTCLR. GTCR is set immediately after
+     * clearing the module stop bit to ensure the timer is stopped before proceeding with configuration. */
+    p_instance_ctrl->p_reg->GTWP  = GPT_PRV_GTWP_RESET_VALUE;
+    p_instance_ctrl->p_reg->GTCR  = 0U;
+    p_instance_ctrl->p_reg->GTST  = 0U;
+    p_instance_ctrl->p_reg->GTCNT = 0U;
+
+    /* GTPR, GTCCRn, GTIOR, GTSSR, GTPSR, GTCSR, GTUPSR, GTDNSR, GTPBR, and GTUDDTYC are set by this driver. */
+
+    /* Initialization sets all register required for up counting as described in hardware manual
+     * (see Section "Counter Operation" in the RZ microprocessor User's Manual for details) and
+     * other registers required by the driver. */
+
+    /* Dividers for GPT are half the enum value. */
+    uint32_t gtcr_tpcs = p_cfg->source_div;
+    uint32_t gtcr      = ((uint32_t) (p_extend->icds << R_GPT7_GTCR_ICDS_Pos) | (gtcr_tpcs << R_GPT7_GTCR_TPCS_Pos));
+
+    /* Store period register setting. The actual period and is one cycle longer than the register value for saw waves
+     * and twice the register value for triangle waves. Reference section 19.2.21 "General PWM Timer Cycle Setting
+     * Register (GTPR)". The setting passed to the configuration is expected to be half the desired period for
+     * triangle waves. */
+    uint32_t gtpr = p_cfg->period_counts - 1U;
+#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+    /* Saw-wave PWM mode is set in GTCR.MD for all modes except TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM and
+     * TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM. */
+    if (p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
+    {
+        gtcr |= ((uint32_t) p_cfg->mode << R_GPT7_GTCR_MD_Pos);
+        gtpr  = p_cfg->period_counts;
+    }
+#endif
+
+    /* Counter must be stopped to update TPCS (see Section "General PWM Timer Control Register (GTCR)"
+     * in the RZ microprocessor User's Manual for details). */
+    p_instance_ctrl->p_reg->GTCR = gtcr;
+
+    gpt_hardware_events_disable(p_instance_ctrl);
+
+    /* Configure the up/down count sources. These are not affected by enable/disable. */
+    p_instance_ctrl->p_reg->GTUPSR = p_extend->count_up_source;
+    p_instance_ctrl->p_reg->GTDNSR = p_extend->count_down_source;
+
+    /* Set period. The actual period is one cycle longer than the register value. Reference section 19.2.21
+     * "General PWM Timer Cycle Setting Register (GTPR)". */
+    p_instance_ctrl->p_reg->GTPBR = gtpr;
+    p_instance_ctrl->p_reg->GTPR  = gtpr;
+}
+
+/*******************************************************************************************************************//**
+ * Disables hardware events that would cause the timer to start, stop, clear, or capture.
+ *
+ * @param[in]  p_instance_ctrl         Instance control structure
+ **********************************************************************************************************************/
+static void gpt_hardware_events_disable (gpt_instance_ctrl_t * p_instance_ctrl)
+{
+    /* Enable use of GTSTR, GTSTP, and GTCLR for this channel. */
+    p_instance_ctrl->p_reg->GTSSR   = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
+    p_instance_ctrl->p_reg->GTPSR   = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
+    p_instance_ctrl->p_reg->GTCSR   = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
+    p_instance_ctrl->p_reg->GTICASR = GPT_SOURCE_NONE;
+    p_instance_ctrl->p_reg->GTICBSR = GPT_SOURCE_NONE;
+}
+
+/*******************************************************************************************************************//**
+ * Disables interrupt if it is a valid vector number.
+ *
+ * @param[in]  irq                     Interrupt number
+ **********************************************************************************************************************/
+static void r_gpt_disable_irq (IRQn_Type irq)
+{
+    /* Disable interrupts. */
+    if (irq >= 0)
+    {
+        R_BSP_IrqDisable(irq);
+        R_FSP_IsrContextSet(irq, NULL);
+    }
+}
+
+/*******************************************************************************************************************//**
+ * Configures and enables interrupt if it is a valid vector number.
+ *
+ * @param[in]  irq                     Interrupt number
+ * @param[in]  priority                NVIC priority of the interrupt
+ * @param[in]  p_context               The interrupt context is a pointer to data required in the ISR.
+ **********************************************************************************************************************/
+static void r_gpt_enable_irq (IRQn_Type const irq, uint32_t priority, void * p_context)
+{
+    if (irq >= 0)
+    {
+        R_BSP_IrqCfgEnable(irq, priority, p_context);
+    }
+}
+
+/*******************************************************************************************************************//**
+ * Disable interrupts
+ *
+ * @param[in]  p_instance_ctrl           Instance control block
+ **********************************************************************************************************************/
+static void gpt_disable_interrupt (gpt_instance_ctrl_t * const p_instance_ctrl)
+{
+    gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
+    if (p_instance_ctrl->p_cfg->cycle_end_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD &= ~(1U << R_GPT7_GTINTAD_GTINTPR_Pos);
+    }
+
+    if (p_extend->capture_a_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD_b.GTINTA = 0U;
+    }
+
+    if (p_extend->capture_b_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD_b.GTINTB = 0U;
+    }
+
+    if (p_extend->dead_time_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD_b.GRPDTE = 0U;
+    }
+
+    r_gpt_disable_irq(p_instance_ctrl->p_cfg->cycle_end_irq);
+    r_gpt_disable_irq(p_extend->capture_a_irq);
+    r_gpt_disable_irq(p_extend->capture_b_irq);
+    r_gpt_disable_irq(p_extend->dead_time_irq);
+#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    gpt_extended_pwm_cfg_t const * p_pwm_cfg = p_extend->p_pwm_cfg;
+    if (NULL != p_pwm_cfg)
+    {
+        if (p_pwm_cfg->trough_irq > FSP_INVALID_VECTOR)
+        {
+            p_instance_ctrl->p_reg->GTINTAD &= ~(2U << R_GPT7_GTINTAD_GTINTPR_Pos);
+        }
+
+        r_gpt_disable_irq(p_pwm_cfg->trough_irq);
+    }
+#endif
+}
+
+/*******************************************************************************************************************//**
+ * Enable interrupts
+ *
+ * @param[in]  p_instance_ctrl           Instance control block
+ **********************************************************************************************************************/
+static void gpt_enable_interrupt (gpt_instance_ctrl_t * const p_instance_ctrl)
+{
+    gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
+
+    /* Enable CPU interrupts if callback is not null.  Also enable interrupts for one shot mode.
+     *  @note The GPT hardware does not support one-shot mode natively. To support one-shot mode, the timer will be
+     *  stopped and cleared using software in the ISR. */
+    if (p_instance_ctrl->p_cfg->cycle_end_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD_b.GTINTPR |= 0x01U;
+    }
+
+    if (p_extend->capture_a_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD_b.GTINTA = 1U;
+    }
+
+    if (p_extend->capture_b_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD_b.GTINTB = 1U;
+    }
+
+    if (p_extend->dead_time_irq > FSP_INVALID_VECTOR)
+    {
+        p_instance_ctrl->p_reg->GTINTAD_b.GRPDTE = 1U;
+    }
+
+    r_gpt_enable_irq(p_instance_ctrl->p_cfg->cycle_end_irq, p_instance_ctrl->p_cfg->cycle_end_ipl, p_instance_ctrl);
+    r_gpt_enable_irq(p_extend->capture_a_irq, p_extend->capture_a_ipl, p_instance_ctrl);
+    r_gpt_enable_irq(p_extend->capture_b_irq, p_extend->capture_b_ipl, p_instance_ctrl);
+    r_gpt_enable_irq(p_extend->dead_time_irq, p_extend->dead_time_ipl, p_instance_ctrl);
+#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    gpt_extended_pwm_cfg_t const * p_pwm_cfg = p_extend->p_pwm_cfg;
+    if (NULL != p_pwm_cfg)
+    {
+        if (p_pwm_cfg->trough_irq > FSP_INVALID_VECTOR)
+        {
+            p_instance_ctrl->p_reg->GTINTAD_b.GTINTPR |= 0x02U;
+        }
+
+        r_gpt_enable_irq(p_pwm_cfg->trough_irq, p_pwm_cfg->trough_ipl, p_instance_ctrl);
+    }
+#endif
+}
+
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+/*******************************************************************************************************************//**
+ * Calculates duty cycle register values.  GTPR must be set before entering this function.
+ *
+ * @param[in]  p_instance_ctrl         Instance control structure
+ * @param[in]  duty_cycle_counts       Duty cycle to set
+ * @param[out] p_duty_reg              Duty cycle register values
+ **********************************************************************************************************************/
+static void gpt_calculate_duty_cycle (gpt_instance_ctrl_t * const p_instance_ctrl,
+                                      uint32_t const              duty_cycle_counts,
+                                      gpt_prv_duty_registers_t  * p_duty_reg)
+{
+    /* Determine the current period. The actual period is one cycle longer than the register value for saw waves
+     * and twice the register value for triangle waves. Reference section 19.2.21 "General PWM Timer Cycle Setting
+     * Register (GTPR)". The setting passed to the configuration is expected to be half the desired duty cycle for
+     * triangle waves. */
+    uint32_t current_period = p_instance_ctrl->p_reg->GTPR;
+ #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    if (p_instance_ctrl->p_cfg->mode < TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
+ #endif
+    {
+        current_period++;
+    }
+
+    /* 0% and 100% duty cycle are supported in OADTY/OBDTY. */
+    if (0U == duty_cycle_counts)
+    {
+        p_duty_reg->omdty = GPT_DUTY_CYCLE_MODE_0_PERCENT;
+    }
+    else if (duty_cycle_counts >= current_period)
+    {
+        p_duty_reg->omdty = GPT_DUTY_CYCLE_MODE_100_PERCENT;
+    }
+    else
+    {
+        uint32_t temp_duty_cycle = duty_cycle_counts;
+
+ #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+        if (p_instance_ctrl->p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
+        {
+            p_duty_reg->gtccr_buffer = temp_duty_cycle;
+        }
+        else
+ #endif
+        {
+            /* The GTIOCA/GTIOCB pins transition 1 cycle after compare match when buffer operation is used (see
+             * Section "PWM Output Operating Mode" in the RZ microprocessor User's Manual for details). */
+            temp_duty_cycle--;
+            p_duty_reg->gtccr_buffer = temp_duty_cycle;
+        }
+    }
+}
+
+#endif
+
+/*******************************************************************************************************************//**
+ * Calculates clock frequency of GPT counter.  Divides GPT clock by GPT clock divisor.
+ *
+ * @param[in]  p_instance_ctrl           Instance control block
+ *
+ * @return     Clock frequency of the GPT counter.
+ **********************************************************************************************************************/
+static uint32_t gpt_clock_frequency_get (gpt_instance_ctrl_t * const p_instance_ctrl)
+{
+    uint32_t pclk_freq_hz;
+
+    /* Look up PCLK frequency and divide it by GPT PCLK divider. */
+    timer_source_div_t pclk_divisor = (timer_source_div_t) (p_instance_ctrl->p_reg->GTCR_b.TPCS);
+    if (0U < (p_instance_ctrl->channel_mask & BSP_FEATURE_GPT_LLPP_CHANNEL_MASK))
+    {
+        pclk_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_PCLKGPTL);
+    }
+    else
+    {
+        pclk_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_PCLKM);
+    }
+
+    return pclk_freq_hz >> pclk_divisor;
+}
+
+#if GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+/*******************************************************************************************************************//**
+ * Calculates GTIOR settings for given mode and stop level.
+ *
+ * @param[in]  p_instance_ctrl         Instance control block
+ * @param[in]  p_cfg                   Timer configuration
+ * @param[in]  level                   Output level after timer stops
+ **********************************************************************************************************************/
+static uint32_t gpt_gtior_calculate (timer_cfg_t const * const p_cfg, gpt_pin_level_t const stop_level)
+{
+    /* The stop level is used as both the initial level and the stop level. */
+    uint32_t gtior = R_GPT7_GTIOR_OAE_Msk | ((uint32_t) stop_level << R_GPT7_GTIOR_OADFLT_Pos) |
+                     ((uint32_t) stop_level << GPT_PRV_GTIOR_INITIAL_LEVEL_BIT);
+
+    uint32_t gtion = GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END;
+
+    if (TIMER_MODE_PWM == p_cfg->mode)
+    {
+        /* Use default: GTIOn is high at cycle end, then low at compare match. */
+    }
+
+ #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+    else if (p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
+    {
+        gtion = GPT_PRV_GTIO_TOGGLE_COMPARE_MATCH;
+    }
+ #endif
+    else
+    {
+        /* In one-shot mode, the output pin goes high after the first compare match (one cycle after the timer starts counting). */
+        if (GPT_PIN_LEVEL_LOW == stop_level)
+        {
+            gtion = GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END;
+        }
+    }
+
+    gtior |= gtion;
+
+    return gtior;
+}
+
+#endif
+
+/*******************************************************************************************************************//**
+ * Calls user callback.
+ *
+ * @param[in]     p_ctrl     Pointer to GPT instance control block
+ * @param[in]     event      Event code
+ * @param[in]     capture    Event capture counts (if applicable)
+ **********************************************************************************************************************/
+static void r_gpt_call_callback (gpt_instance_ctrl_t * p_ctrl, timer_event_t event, uint32_t capture)
+{
+    timer_callback_args_t args;
+
+    /* Store callback arguments in memory provided by user if available.  This allows callback arguments to be
+     * stored in non-secure memory so they can be accessed by a non-secure callback function. */
+    timer_callback_args_t * p_args = p_ctrl->p_callback_memory;
+    if (NULL == p_args)
+    {
+        /* Store on stack */
+        p_args = &args;
+    }
+    else
+    {
+        /* Save current arguments on the stack in case this is a nested interrupt. */
+        args = *p_args;
+    }
+
+    p_args->event     = event;
+    p_args->capture   = capture;
+    p_args->p_context = p_ctrl->p_context;
+
+    /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
+    p_ctrl->p_callback(p_args);
+
+    if (NULL != p_ctrl->p_callback_memory)
+    {
+        /* Restore callback memory in case this is a nested interrupt. */
+        *p_ctrl->p_callback_memory = args;
+    }
+}
+
+/*******************************************************************************************************************//**
+ * Common processing for input capture interrupt.
+ *
+ * @param[in]  event  Which input capture event occurred
+ **********************************************************************************************************************/
+static void r_gpt_capture_common_isr (gpt_prv_capture_event_t event)
+{
+    GPT_CFG_MULTIPLEX_INTERRUPT_ENABLE;
+
+    /* Save context if RTOS is used */
+    FSP_CONTEXT_SAVE;
+
+    IRQn_Type irq = R_FSP_CurrentIrqGet();
+
+    /* Recover ISR context saved in open. */
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
+    uint32_t              counter;
+
+    /* Get captured value. */
+    if (event == GPT_PRV_CAPTURE_EVENT_A)
+    {
+        counter = p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRA];
+    }
+    else
+    {
+        counter = p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRB];
+    }
+
+    /* If we captured a one-shot pulse, then disable future captures. */
+    if (TIMER_MODE_ONE_SHOT == p_instance_ctrl->p_cfg->mode)
+    {
+        /* Disable captures. */
+        gpt_hardware_events_disable(p_instance_ctrl);
+
+        /* Clear pending interrupt to make sure it doesn't fire again if another overflow has already occurred. */
+        R_BSP_IrqClearPending(irq);
+    }
+
+    /* If a callback is provided, then call it with the captured counter value. */
+    if (NULL != p_instance_ctrl->p_callback)
+    {
+        r_gpt_call_callback(p_instance_ctrl,
+                            (timer_event_t) ((uint32_t) TIMER_EVENT_CAPTURE_A + (uint32_t) event),
+                            counter);
+    }
+
+    /* Restore context if RTOS is used */
+    FSP_CONTEXT_RESTORE;
+
+    GPT_CFG_MULTIPLEX_INTERRUPT_DISABLE;
+}
+
+/*******************************************************************************************************************//**
+ * Stops the timer if one-shot mode, clears interrupts, and calls callback if one was provided in the open function.
+ **********************************************************************************************************************/
+void gpt_counter_overflow_isr (void)
+{
+    GPT_CFG_MULTIPLEX_INTERRUPT_ENABLE;
+
+    /* Save context if RTOS is used */
+    FSP_CONTEXT_SAVE;
+
+    IRQn_Type irq = R_FSP_CurrentIrqGet();
+
+    /* Recover ISR context saved in open. */
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
+
+    /* If one-shot mode is selected, stop the timer since period has expired. */
+    if (TIMER_MODE_ONE_SHOT == p_instance_ctrl->p_cfg->mode)
+    {
+        r_gpt_write_protect_disable(p_instance_ctrl);
+
+        p_instance_ctrl->p_reg->GTSTP = p_instance_ctrl->channel_mask;
+
+        /* Clear the GPT counter and the overflow flag after the one shot pulse has being generated */
+        p_instance_ctrl->p_reg->GTCNT                 = 0;
+        p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRA] = 0;
+        p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRB] = 0;
+
+        r_gpt_write_protect_enable(p_instance_ctrl);
+
+        /* Clear pending interrupt to make sure it doesn't fire again if another overflow has already occurred. */
+        R_BSP_IrqClearPending(irq);
+    }
+
+    if (NULL != p_instance_ctrl->p_callback)
+    {
+        r_gpt_call_callback(p_instance_ctrl, TIMER_EVENT_CYCLE_END, 0);
+    }
+
+    /* Restore context if RTOS is used */
+    FSP_CONTEXT_RESTORE;
+
+    GPT_CFG_MULTIPLEX_INTERRUPT_DISABLE;
+}
+
+#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
+
+/*******************************************************************************************************************//**
+ * Only supported for asymmetric triangle-wave PWM. Notifies application of trough event.
+ **********************************************************************************************************************/
+void gpt_counter_underflow_isr (void)
+{
+    GPT_CFG_MULTIPLEX_INTERRUPT_ENABLE;
+
+    /* Save context if RTOS is used */
+    FSP_CONTEXT_SAVE;
+
+    IRQn_Type irq = R_FSP_CurrentIrqGet();
+
+    /* Recover ISR context saved in open. */
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
+
+    /* Call user callback. */
+    r_gpt_call_callback(p_instance_ctrl, TIMER_EVENT_TROUGH, 0);
+
+    /* Restore context if RTOS is used */
+    FSP_CONTEXT_RESTORE;
+
+    GPT_CFG_MULTIPLEX_INTERRUPT_DISABLE;
+}
+
+#endif
+
+/*******************************************************************************************************************//**
+ * Calls callback if one was provided in the open function.
+ **********************************************************************************************************************/
+void gpt_dead_time_isr (void)
+{
+    GPT_CFG_MULTIPLEX_INTERRUPT_ENABLE;
+
+    /* Save context if RTOS is used */
+    FSP_CONTEXT_SAVE;
+
+    IRQn_Type irq = R_FSP_CurrentIrqGet();
+
+    /* Recover ISR context saved in open. */
+    gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
+
+    /* Call user callback. */
+    r_gpt_call_callback(p_instance_ctrl, TIMER_EVENT_DEAD_TIME, 0);
+
+    /* Restore context if RTOS is used */
+    FSP_CONTEXT_RESTORE;
+
+    GPT_CFG_MULTIPLEX_INTERRUPT_DISABLE;
+}
+
+/*******************************************************************************************************************//**
+ * Interrupt triggered by a capture A source.
+ *
+ * Clears interrupt, disables captures if one-shot mode, and calls callback if one was provided in the open function.
+ **********************************************************************************************************************/
+void gpt_capture_a_isr (void)
+{
+    r_gpt_capture_common_isr(GPT_PRV_CAPTURE_EVENT_A);
+}
+
+/*******************************************************************************************************************//**
+ * Interrupt triggered by a capture B source.
+ *
+ * Clears interrupt, disables captures if one-shot mode, and calls callback if one was provided in the open function.
+ **********************************************************************************************************************/
+void gpt_capture_b_isr (void)
+{
+    r_gpt_capture_common_isr(GPT_PRV_CAPTURE_EVENT_B);
+}

+ 81 - 0
projects/etherkit_ethercat_coe/rzn_cfg/fsp_cfg/r_canfd_cfg.h

@@ -0,0 +1,81 @@
+/* generated configuration header file - do not edit */
+#ifndef R_CANFD_CFG_H_
+#define R_CANFD_CFG_H_
+/* Buffer RAM used: 2432 bytes */
+
+            #define CANFD_CFG_PARAM_CHECKING_ENABLE   ((BSP_CFG_PARAM_CHECKING_ENABLE))
+
+            #define CANFD_CFG_MULTIPLEX_INTERRUPT_SUPPORTED (0)
+            #if CANFD_CFG_MULTIPLEX_INTERRUPT_SUPPORTED
+             #define CANFD_CFG_MULTIPLEX_INTERRUPT_ENABLE         BSP_INTERRUPT_ENABLE
+             #define CANFD_CFG_MULTIPLEX_INTERRUPT_DISABLE        BSP_INTERRUPT_DISABLE
+            #else
+             #define CANFD_CFG_MULTIPLEX_INTERRUPT_ENABLE
+             #define CANFD_CFG_MULTIPLEX_INTERRUPT_DISABLE
+            #endif
+
+            #define CANFD_CFG_AFL_CH0_RULE_NUM   (64)
+            #define CANFD_CFG_AFL_CH1_RULE_NUM   (64)
+
+            #define CANFD_CFG_GLOBAL_ERROR_CH    ((1U))
+
+            #define CANFD_CFG_FD_PROTOCOL_EXCEPTION   ((0))
+
+            #define CANFD_CFG_GLOBAL_ERR_SOURCES    ( 0x3)
+            #define CANFD_CFG_TX_PRIORITY           ((R_CANFD_CFDGCFG_TPRI_Msk))
+            #define CANFD_CFG_DLC_CHECK             ((0))
+            #define CANFD_CFD_CLOCK_SOURCE          ((R_CANFD_CFDGCFG_DCS_Msk))
+            #define CANFD_CFG_FD_OVERFLOW           ((0))
+            #define CANFD_CFG_RXMB_NUMBER           (0)
+            #define CANFD_CFG_RXMB_SIZE             ((0))
+            #define CANFD_CFG_GLOBAL_ERR_IPL        ((12))
+            #define CANFD_CFG_RX_FIFO_IPL           ((12))
+
+            #define CANFD_CFG_RXFIFO0_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO0_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO0_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO0_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO0_ENABLE        ((1))
+
+            #define CANFD_CFG_RXFIFO1_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO1_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO1_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO1_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO1_ENABLE        ((1))
+
+            #define CANFD_CFG_RXFIFO2_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO2_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO2_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO2_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO2_ENABLE        ((0))
+
+            #define CANFD_CFG_RXFIFO3_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO3_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO3_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO3_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO3_ENABLE        ((0))
+
+            #define CANFD_CFG_RXFIFO4_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO4_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO4_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO4_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO4_ENABLE        ((0))
+
+            #define CANFD_CFG_RXFIFO5_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO5_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO5_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO5_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO5_ENABLE        ((0))
+
+            #define CANFD_CFG_RXFIFO6_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO6_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO6_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO6_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO6_ENABLE        ((0))
+
+            #define CANFD_CFG_RXFIFO7_INT_THRESHOLD ((3U))
+            #define CANFD_CFG_RXFIFO7_DEPTH         ((3))
+            #define CANFD_CFG_RXFIFO7_PAYLOAD       ((7))
+            #define CANFD_CFG_RXFIFO7_INT_MODE      ((R_CANFD_CFDRFCC_RFIE_Msk | R_CANFD_CFDRFCC_RFIM_Msk))
+            #define CANFD_CFG_RXFIFO7_ENABLE        ((0))
+#endif /* R_CANFD_CFG_H_ */

+ 16 - 0
projects/etherkit_ethercat_coe/rzn_cfg/fsp_cfg/r_gpt_cfg.h

@@ -0,0 +1,16 @@
+/* generated configuration header file - do not edit */
+#ifndef R_GPT_CFG_H_
+#define R_GPT_CFG_H_
+#define GPT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE)
+#define GPT_CFG_OUTPUT_SUPPORT_ENABLE (0)
+#define GPT_CFG_WRITE_PROTECT_ENABLE (0)
+
+#define GPT_CFG_MULTIPLEX_INTERRUPT_SUPPORTED (0)
+#if GPT_CFG_MULTIPLEX_INTERRUPT_SUPPORTED
+ #define GPT_CFG_MULTIPLEX_INTERRUPT_ENABLE         BSP_INTERRUPT_ENABLE
+ #define GPT_CFG_MULTIPLEX_INTERRUPT_DISABLE        BSP_INTERRUPT_DISABLE
+#else
+ #define GPT_CFG_MULTIPLEX_INTERRUPT_ENABLE
+ #define GPT_CFG_MULTIPLEX_INTERRUPT_DISABLE
+#endif
+#endif /* R_GPT_CFG_H_ */

+ 268 - 0
projects/etherkit_ethercat_coe/rzn_gen/hal_data.c

@@ -1,5 +1,273 @@
 /* generated HAL source file - do not edit */
 #include "hal_data.h"
+
+gpt_instance_ctrl_t g_timer1_ctrl;
+#if 0
+const gpt_extended_pwm_cfg_t g_timer1_pwm_extend =
+{
+    .trough_ipl          = (BSP_IRQ_DISABLED),
+#if defined(VECTOR_NUMBER_GPT8_UDF)
+    .trough_irq          = VECTOR_NUMBER_GPT8_UDF,
+#else
+    .trough_irq          = FSP_INVALID_VECTOR,
+#endif
+    .poeg_link           = GPT_POEG_LINK_POEG0,
+    .output_disable      =  GPT_OUTPUT_DISABLE_NONE,
+    .adc_trigger         =  GPT_ADC_TRIGGER_NONE,
+    .dead_time_count_up  = 0,
+    .dead_time_count_down = 0,
+    .adc_a_compare_match = 0,
+    .adc_b_compare_match = 0,
+    .interrupt_skip_source = GPT_INTERRUPT_SKIP_SOURCE_NONE,
+    .interrupt_skip_count  = GPT_INTERRUPT_SKIP_COUNT_0,
+    .interrupt_skip_adc    = GPT_INTERRUPT_SKIP_ADC_NONE,
+    .gtioca_disable_setting = GPT_GTIOC_DISABLE_PROHIBITED,
+    .gtiocb_disable_setting = GPT_GTIOC_DISABLE_PROHIBITED,
+    .interrupt_skip_source_ext1 = GPT_INTERRUPT_SKIP_SOURCE_NONE,
+    .interrupt_skip_count_ext1  = GPT_INTERRUPT_SKIP_COUNT_0,
+    .interrupt_skip_source_ext2 = GPT_INTERRUPT_SKIP_SOURCE_NONE,
+    .interrupt_skip_count_ext2  = GPT_INTERRUPT_SKIP_COUNT_0,
+    .interrupt_skip_func_ovf    = GPT_INTERRUPT_SKIP_SELECT_NONE,
+    .interrupt_skip_func_unf    = GPT_INTERRUPT_SKIP_SELECT_NONE,
+    .interrupt_skip_func_adc_a  = GPT_INTERRUPT_SKIP_SELECT_NONE,
+    .interrupt_skip_func_adc_b  = GPT_INTERRUPT_SKIP_SELECT_NONE,
+};
+#endif
+const gpt_extended_cfg_t g_timer1_extend =
+{
+    .gtioca = { .output_enabled = false,
+                .stop_level     = GPT_PIN_LEVEL_LOW
+              },
+    .gtiocb = { .output_enabled = false,
+                .stop_level     = GPT_PIN_LEVEL_LOW
+              },
+    .start_source        = (gpt_source_t) ( GPT_SOURCE_NONE),
+    .stop_source         = (gpt_source_t) ( GPT_SOURCE_NONE),
+    .clear_source        = (gpt_source_t) ( GPT_SOURCE_NONE),
+#if (0 == (0))
+    .count_up_source     = (gpt_source_t) ( GPT_SOURCE_NONE),
+    .count_down_source   = (gpt_source_t) ( GPT_SOURCE_NONE),
+#else
+    .count_up_source     = (gpt_source_t) ((GPT_PHASE_COUNTING_MODE_1_UP | (GPT_PHASE_COUNTING_MODE_1_DN << 16)) & 0x000FFFFU),
+    .count_down_source   = (gpt_source_t) (((GPT_PHASE_COUNTING_MODE_1_UP | (GPT_PHASE_COUNTING_MODE_1_DN << 16)) & 0xFFFF0000U) >> 16),
+#endif
+    .capture_a_source    = (gpt_source_t) ( GPT_SOURCE_NONE),
+    .capture_b_source    = (gpt_source_t) ( GPT_SOURCE_NONE),
+    .capture_a_ipl       = (BSP_IRQ_DISABLED),
+    .capture_b_ipl       = (BSP_IRQ_DISABLED),
+#if defined(VECTOR_NUMBER_GPT8_CCMPA)
+    .capture_a_irq       = VECTOR_NUMBER_GPT8_CCMPA,
+#else
+    .capture_a_irq       = FSP_INVALID_VECTOR,
+#endif
+#if defined(VECTOR_NUMBER_GPT8_CCMPB)
+    .capture_b_irq       = VECTOR_NUMBER_GPT8_CCMPB,
+#else
+    .capture_b_irq       = FSP_INVALID_VECTOR,
+#endif
+    .capture_filter_gtioca       = GPT_CAPTURE_FILTER_NONE,
+    .capture_filter_gtiocb       = GPT_CAPTURE_FILTER_NONE,
+#if 0
+    .p_pwm_cfg                   = &g_timer1_pwm_extend,
+#else
+    .p_pwm_cfg                   = NULL,
+#endif
+    .dead_time_ipl       = (BSP_IRQ_DISABLED),
+#if defined(VECTOR_NUMBER_GPT8_DTE)
+    .dead_time_irq       = VECTOR_NUMBER_GPT8_DTE,
+#else
+    .dead_time_irq       = FSP_INVALID_VECTOR,
+#endif
+    .icds                = 0,
+};
+const timer_cfg_t g_timer1_cfg =
+{
+    .mode                = TIMER_MODE_PERIODIC,
+    /* Actual period: 42.94967296 seconds. Actual duty: 50%. */ .period_counts = (uint32_t) 0x100000000, .duty_cycle_counts = 0x80000000, .source_div = (timer_source_div_t)0,
+    .channel             = GPT_CHANNEL_UNIT1_1,
+    .p_callback          = timer1_callback,
+    .p_context           = NULL,
+    .p_extend            = &g_timer1_extend,
+    .cycle_end_ipl       = (12),
+#if defined(VECTOR_NUMBER_GPT8_OVF)
+    .cycle_end_irq       = VECTOR_NUMBER_GPT8_OVF,
+#else
+    .cycle_end_irq       = FSP_INVALID_VECTOR,
+#endif
+};
+/* Instance structure to use this module. */
+const timer_instance_t g_timer1 =
+{
+    .p_ctrl        = &g_timer1_ctrl,
+    .p_cfg         = &g_timer1_cfg,
+    .p_api         = &g_timer_on_gpt
+};
+/* Nominal and Data bit timing configuration */
+
+can_bit_timing_cfg_t g_canfd1_bit_timing_cfg =
+{
+    /* Actual bitrate: 1000000 Hz. Actual sample point: 75 %. */
+    .baud_rate_prescaler = 1,
+    .time_segment_1 = 29,
+    .time_segment_2 = 10,
+    .synchronization_jump_width = 4
+};
+
+can_bit_timing_cfg_t g_canfd1_data_timing_cfg =
+{
+    /* Actual bitrate: 1000000 Hz. Actual sample point: 75 %. */
+    .baud_rate_prescaler = 1,
+    .time_segment_1 = 29,
+    .time_segment_2 = 10,
+    .synchronization_jump_width = 4
+};
+
+
+extern const canfd_afl_entry_t p_canfd1_afl[CANFD_CFG_AFL_CH1_RULE_NUM];
+
+#ifndef CANFD_PRV_GLOBAL_CFG
+#define CANFD_PRV_GLOBAL_CFG
+canfd_global_cfg_t g_canfd_global_cfg =
+{
+    .global_interrupts = CANFD_CFG_GLOBAL_ERR_SOURCES,
+    .global_config     = (CANFD_CFG_TX_PRIORITY | CANFD_CFG_DLC_CHECK | CANFD_CFD_CLOCK_SOURCE | CANFD_CFG_FD_OVERFLOW),
+    .rx_mb_config      = (CANFD_CFG_RXMB_NUMBER | (CANFD_CFG_RXMB_SIZE << R_CANFD_CFDRMNB_RMPLS_Pos)),
+    .global_err_ipl = CANFD_CFG_GLOBAL_ERR_IPL,
+    .rx_fifo_ipl    = CANFD_CFG_RX_FIFO_IPL,
+    .rx_fifo_config    =
+    {
+        ((CANFD_CFG_RXFIFO0_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO0_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO0_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO0_INT_MODE) | (CANFD_CFG_RXFIFO0_ENABLE)),
+        ((CANFD_CFG_RXFIFO1_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO1_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO1_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO1_INT_MODE) | (CANFD_CFG_RXFIFO1_ENABLE)),
+        ((CANFD_CFG_RXFIFO2_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO2_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO2_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO2_INT_MODE) | (CANFD_CFG_RXFIFO2_ENABLE)),
+        ((CANFD_CFG_RXFIFO3_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO3_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO3_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO3_INT_MODE) | (CANFD_CFG_RXFIFO3_ENABLE)),
+        ((CANFD_CFG_RXFIFO4_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO4_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO4_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO4_INT_MODE) | (CANFD_CFG_RXFIFO4_ENABLE)),
+        ((CANFD_CFG_RXFIFO5_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO5_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO5_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO5_INT_MODE) | (CANFD_CFG_RXFIFO5_ENABLE)),
+        ((CANFD_CFG_RXFIFO6_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO6_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO6_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO6_INT_MODE) | (CANFD_CFG_RXFIFO6_ENABLE)),
+        ((CANFD_CFG_RXFIFO7_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO7_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO7_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO7_INT_MODE) | (CANFD_CFG_RXFIFO7_ENABLE)),
+    },
+};
+#endif
+
+canfd_extended_cfg_t g_canfd1_extended_cfg =
+{
+    .p_afl              = p_canfd1_afl,
+    .txmb_txi_enable    = ((1ULL << 0) | (1ULL << 1) |  0ULL),
+    .error_interrupts   = ( 0U),
+    .p_data_timing      = &g_canfd1_data_timing_cfg,
+    .delay_compensation = (1),
+    .p_global_cfg       = &g_canfd_global_cfg,
+};
+
+canfd_instance_ctrl_t g_canfd1_ctrl;
+const can_cfg_t g_canfd1_cfg =
+{
+    .channel                = 1,
+    .p_bit_timing           = &g_canfd1_bit_timing_cfg,
+    .p_callback             = canfd1_callback,
+    .p_extend               = &g_canfd1_extended_cfg,
+    .p_context              = NULL,
+    .ipl                    = (12),
+#if defined(VECTOR_NUMBER_CAN1_TX)
+    .tx_irq             = VECTOR_NUMBER_CAN1_TX,
+#else
+    .tx_irq             = FSP_INVALID_VECTOR,
+#endif
+#if defined(VECTOR_NUMBER_CAN1_CHERR)
+    .error_irq             = VECTOR_NUMBER_CAN1_CHERR,
+#else
+    .error_irq             = FSP_INVALID_VECTOR,
+#endif
+};
+/* Instance structure to use this module. */
+const can_instance_t g_canfd1 =
+{
+    .p_ctrl        = &g_canfd1_ctrl,
+    .p_cfg         = &g_canfd1_cfg,
+    .p_api         = &g_canfd_on_canfd
+};
+/* Nominal and Data bit timing configuration */
+
+can_bit_timing_cfg_t g_canfd0_bit_timing_cfg =
+{
+    /* Actual bitrate: 1000000 Hz. Actual sample point: 75 %. */
+    .baud_rate_prescaler = 1,
+    .time_segment_1 = 29,
+    .time_segment_2 = 10,
+    .synchronization_jump_width = 4
+};
+
+can_bit_timing_cfg_t g_canfd0_data_timing_cfg =
+{
+    /* Actual bitrate: 1000000 Hz. Actual sample point: 75 %. */
+    .baud_rate_prescaler = 1,
+    .time_segment_1 = 29,
+    .time_segment_2 = 10,
+    .synchronization_jump_width = 4
+};
+
+
+extern const canfd_afl_entry_t p_canfd0_afl[CANFD_CFG_AFL_CH0_RULE_NUM];
+
+#ifndef CANFD_PRV_GLOBAL_CFG
+#define CANFD_PRV_GLOBAL_CFG
+canfd_global_cfg_t g_canfd_global_cfg =
+{
+    .global_interrupts = CANFD_CFG_GLOBAL_ERR_SOURCES,
+    .global_config     = (CANFD_CFG_TX_PRIORITY | CANFD_CFG_DLC_CHECK | CANFD_CFD_CLOCK_SOURCE | CANFD_CFG_FD_OVERFLOW),
+    .rx_mb_config      = (CANFD_CFG_RXMB_NUMBER | (CANFD_CFG_RXMB_SIZE << R_CANFD_CFDRMNB_RMPLS_Pos)),
+    .global_err_ipl = CANFD_CFG_GLOBAL_ERR_IPL,
+    .rx_fifo_ipl    = CANFD_CFG_RX_FIFO_IPL,
+    .rx_fifo_config    =
+    {
+        ((CANFD_CFG_RXFIFO0_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO0_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO0_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO0_INT_MODE) | (CANFD_CFG_RXFIFO0_ENABLE)),
+        ((CANFD_CFG_RXFIFO1_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO1_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO1_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO1_INT_MODE) | (CANFD_CFG_RXFIFO1_ENABLE)),
+        ((CANFD_CFG_RXFIFO2_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO2_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO2_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO2_INT_MODE) | (CANFD_CFG_RXFIFO2_ENABLE)),
+        ((CANFD_CFG_RXFIFO3_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO3_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO3_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO3_INT_MODE) | (CANFD_CFG_RXFIFO3_ENABLE)),
+        ((CANFD_CFG_RXFIFO4_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO4_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO4_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO4_INT_MODE) | (CANFD_CFG_RXFIFO4_ENABLE)),
+        ((CANFD_CFG_RXFIFO5_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO5_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO5_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO5_INT_MODE) | (CANFD_CFG_RXFIFO5_ENABLE)),
+        ((CANFD_CFG_RXFIFO6_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO6_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO6_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO6_INT_MODE) | (CANFD_CFG_RXFIFO6_ENABLE)),
+        ((CANFD_CFG_RXFIFO7_INT_THRESHOLD << R_CANFD_CFDRFCC_RFIGCV_Pos) | (CANFD_CFG_RXFIFO7_DEPTH << R_CANFD_CFDRFCC_RFDC_Pos) | (CANFD_CFG_RXFIFO7_PAYLOAD << R_CANFD_CFDRFCC_RFPLS_Pos) | (CANFD_CFG_RXFIFO7_INT_MODE) | (CANFD_CFG_RXFIFO7_ENABLE)),
+    },
+};
+#endif
+
+canfd_extended_cfg_t g_canfd0_extended_cfg =
+{
+    .p_afl              = p_canfd0_afl,
+    .txmb_txi_enable    = ((1ULL << 0) | (1ULL << 1) |  0ULL),
+    .error_interrupts   = ( 0U),
+    .p_data_timing      = &g_canfd0_data_timing_cfg,
+    .delay_compensation = (1),
+    .p_global_cfg       = &g_canfd_global_cfg,
+};
+
+canfd_instance_ctrl_t g_canfd0_ctrl;
+const can_cfg_t g_canfd0_cfg =
+{
+    .channel                = 0,
+    .p_bit_timing           = &g_canfd0_bit_timing_cfg,
+    .p_callback             = canfd0_callback,
+    .p_extend               = &g_canfd0_extended_cfg,
+    .p_context              = NULL,
+    .ipl                    = (12),
+#if defined(VECTOR_NUMBER_CAN0_TX)
+    .tx_irq             = VECTOR_NUMBER_CAN0_TX,
+#else
+    .tx_irq             = FSP_INVALID_VECTOR,
+#endif
+#if defined(VECTOR_NUMBER_CAN0_CHERR)
+    .error_irq             = VECTOR_NUMBER_CAN0_CHERR,
+#else
+    .error_irq             = FSP_INVALID_VECTOR,
+#endif
+};
+/* Instance structure to use this module. */
+const can_instance_t g_canfd0 =
+{
+    .p_ctrl        = &g_canfd0_ctrl,
+    .p_cfg         = &g_canfd0_cfg,
+    .p_api         = &g_canfd_on_canfd
+};
 sci_uart_instance_ctrl_t     g_uart0_ctrl;
 
             #define FSP_NOT_DEFINED (1)

+ 40 - 0
projects/etherkit_ethercat_coe/rzn_gen/hal_data.h

@@ -4,9 +4,49 @@
 #include <stdint.h>
 #include "bsp_api.h"
 #include "common_data.h"
+#include "r_gpt.h"
+#include "r_timer_api.h"
+#include "r_canfd.h"
+#include "r_can_api.h"
 #include "r_sci_uart.h"
             #include "r_uart_api.h"
 FSP_HEADER
+/** Timer on GPT Instance. */
+extern const timer_instance_t g_timer1;
+
+/** Access the GPT instance using these structures when calling API functions directly (::p_api is not used). */
+extern gpt_instance_ctrl_t g_timer1_ctrl;
+extern const timer_cfg_t g_timer1_cfg;
+
+#ifndef timer1_callback
+void timer1_callback(timer_callback_args_t * p_args);
+#endif
+/** CANFD on CANFD Instance. */
+extern const can_instance_t g_canfd1;
+/** Access the CANFD instance using these structures when calling API functions directly (::p_api is not used). */
+extern canfd_instance_ctrl_t g_canfd1_ctrl;
+extern const can_cfg_t g_canfd1_cfg;
+extern const canfd_extended_cfg_t g_canfd1_cfg_extend;
+
+#ifndef canfd1_callback
+void canfd1_callback(can_callback_args_t * p_args);
+#endif
+
+/* Global configuration (referenced by all instances) */
+extern canfd_global_cfg_t g_canfd_global_cfg;
+/** CANFD on CANFD Instance. */
+extern const can_instance_t g_canfd0;
+/** Access the CANFD instance using these structures when calling API functions directly (::p_api is not used). */
+extern canfd_instance_ctrl_t g_canfd0_ctrl;
+extern const can_cfg_t g_canfd0_cfg;
+extern const canfd_extended_cfg_t g_canfd0_cfg_extend;
+
+#ifndef canfd0_callback
+void canfd0_callback(can_callback_args_t * p_args);
+#endif
+
+/* Global configuration (referenced by all instances) */
+extern canfd_global_cfg_t g_canfd_global_cfg;
 /** UART on SCI Instance. */
             extern const uart_instance_t      g_uart0;
 

+ 14 - 6
projects/etherkit_ethercat_coe/rzn_gen/pin_data.c

@@ -23,6 +23,10 @@ const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
         .pin = BSP_IO_PORT_00_PIN_3,
         .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P003_PFC_01_ETH2_REFCLK)
     },
+    {
+        .pin = BSP_IO_PORT_00_PIN_5,
+        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P005_PFC_05_GTIOC0B)
+    },
     {
         .pin = BSP_IO_PORT_00_PIN_6,
         .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_CFG_SLEW_RATE_FAST | (uint32_t) IOPORT_PIN_P006_PFC_00_ETH2_TXCLK)
@@ -44,12 +48,12 @@ const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
         .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_CFG_SLEW_RATE_FAST | (uint32_t) IOPORT_PIN_P015_PFC_00_ETH2_TXD0)
     },
     {
-        .pin = BSP_IO_PORT_01_PIN_7,
-        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P017_PFC_08_CANRX0)
+        .pin = BSP_IO_PORT_02_PIN_0,
+        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P020_PFC_07_CANTX1)
     },
     {
-        .pin = BSP_IO_PORT_02_PIN_2,
-        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P022_PFC_08_CANTX0)
+        .pin = BSP_IO_PORT_02_PIN_3,
+        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P023_PFC_09_CANRX1)
     },
     {
         .pin = BSP_IO_PORT_02_PIN_4,
@@ -85,11 +89,11 @@ const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
     },
     {
         .pin = BSP_IO_PORT_05_PIN_2,
-        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P052_PFC_08_IIC_SCL1)
+        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P052_PFC_09_CANRX0)
     },
     {
         .pin = BSP_IO_PORT_05_PIN_3,
-        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P053_PFC_09_IIC_SDA1)
+        .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P053_PFC_0A_CANTX0)
     },
     {
         .pin = BSP_IO_PORT_05_PIN_4,
@@ -331,6 +335,10 @@ const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
         .pin = BSP_IO_PORT_17_PIN_3,
         .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW)
     },
+    {
+        .pin = BSP_IO_PORT_17_PIN_4,
+        .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P174_PFC_03_GTIOC0A)
+    },
     {
         .pin = BSP_IO_PORT_17_PIN_5,
         .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_PERI | (uint32_t) IOPORT_PIN_P175_PFC_05_USB_OVRCUR)

+ 7 - 0
projects/etherkit_ethercat_coe/rzn_gen/vector_data.c

@@ -5,6 +5,7 @@
         BSP_DONT_REMOVE const fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES] =
         {
                         [53] = cmt_cm_int_isr, /* CMT0_CMI (CMT0 Compare match) */
+            [194] = gpt_counter_overflow_isr, /* GPT_OVF (GPT8 GTCNT overflow (GTPR compare match)) */
             [277] = ethercat_ssc_port_isr_esc_sync0, /* ESC_SYNC0 (EtherCAT Sync0 interrupt) */
             [278] = ethercat_ssc_port_isr_esc_sync1, /* ESC_SYNC1 (EtherCAT Sync1 interrupt) */
             [279] = ethercat_ssc_port_isr_esc_cat, /* ESC_CAT (EtherCAT interrupt) */
@@ -12,5 +13,11 @@
             [289] = sci_uart_rxi_isr, /* SCI0_RXI (SCI0 Receive data full) */
             [290] = sci_uart_txi_isr, /* SCI0_TXI (SCI0 Transmit data empty) */
             [291] = sci_uart_tei_isr, /* SCI0_TEI (SCI0 Transmit end) */
+            [316] = canfd_rx_fifo_isr, /* CAN_RXF (CANFD RX FIFO interrupt) */
+            [317] = canfd_error_isr, /* CAN_GLERR (CANFD Global error interrupt) */
+            [318] = canfd_channel_tx_isr, /* CAN0_TX (CANFD0 Channel TX interrupt) */
+            [319] = canfd_error_isr, /* CAN0_CHERR (CANFD0 Channel CAN error interrupt) */
+            [321] = canfd_channel_tx_isr, /* CAN1_TX (CANFD1 Channel TX interrupt) */
+            [322] = canfd_error_isr, /* CAN1_CHERR (CANFD1 Channel CAN error interrupt) */
         };
         #endif

+ 19 - 1
projects/etherkit_ethercat_coe/rzn_gen/vector_data.h

@@ -4,10 +4,11 @@
         #include "bsp_api.h"
                 /* Number of interrupts allocated */
         #ifndef VECTOR_DATA_IRQ_COUNT
-        #define VECTOR_DATA_IRQ_COUNT    (8)
+        #define VECTOR_DATA_IRQ_COUNT    (15)
         #endif
         /* ISR prototypes */
         void cmt_cm_int_isr(void);
+        void gpt_counter_overflow_isr(void);
         void ethercat_ssc_port_isr_esc_sync0(void);
         void ethercat_ssc_port_isr_esc_sync1(void);
         void ethercat_ssc_port_isr_esc_cat(void);
@@ -15,9 +16,13 @@
         void sci_uart_rxi_isr(void);
         void sci_uart_txi_isr(void);
         void sci_uart_tei_isr(void);
+        void canfd_rx_fifo_isr(void);
+        void canfd_error_isr(void);
+        void canfd_channel_tx_isr(void);
 
         /* Vector table allocations */
         #define VECTOR_NUMBER_CMT0_CMI ((IRQn_Type) 53) /* CMT0_CMI (CMT0 Compare match) */
+        #define VECTOR_NUMBER_GPT8_OVF ((IRQn_Type) 194) /* GPT_OVF (GPT8 GTCNT overflow (GTPR compare match)) */
         #define VECTOR_NUMBER_ESC_SYNC0 ((IRQn_Type) 277) /* ESC_SYNC0 (EtherCAT Sync0 interrupt) */
         #define VECTOR_NUMBER_ESC_SYNC1 ((IRQn_Type) 278) /* ESC_SYNC1 (EtherCAT Sync1 interrupt) */
         #define VECTOR_NUMBER_ESC_CAT ((IRQn_Type) 279) /* ESC_CAT (EtherCAT interrupt) */
@@ -25,6 +30,12 @@
         #define VECTOR_NUMBER_SCI0_RXI ((IRQn_Type) 289) /* SCI0_RXI (SCI0 Receive data full) */
         #define VECTOR_NUMBER_SCI0_TXI ((IRQn_Type) 290) /* SCI0_TXI (SCI0 Transmit data empty) */
         #define VECTOR_NUMBER_SCI0_TEI ((IRQn_Type) 291) /* SCI0_TEI (SCI0 Transmit end) */
+        #define VECTOR_NUMBER_CAN_RXF ((IRQn_Type) 316) /* CAN_RXF (CANFD RX FIFO interrupt) */
+        #define VECTOR_NUMBER_CAN_GLERR ((IRQn_Type) 317) /* CAN_GLERR (CANFD Global error interrupt) */
+        #define VECTOR_NUMBER_CAN0_TX ((IRQn_Type) 318) /* CAN0_TX (CANFD0 Channel TX interrupt) */
+        #define VECTOR_NUMBER_CAN0_CHERR ((IRQn_Type) 319) /* CAN0_CHERR (CANFD0 Channel CAN error interrupt) */
+        #define VECTOR_NUMBER_CAN1_TX ((IRQn_Type) 321) /* CAN1_TX (CANFD1 Channel TX interrupt) */
+        #define VECTOR_NUMBER_CAN1_CHERR ((IRQn_Type) 322) /* CAN1_CHERR (CANFD1 Channel CAN error interrupt) */
         typedef enum IRQn {
             SoftwareGeneratedInt0 = -32,
             SoftwareGeneratedInt1 = -31,
@@ -50,6 +61,7 @@
             VirtualTimerInt = -5,
             NonSecurePhysicalTimerInt = -2,
             CMT0_CMI_IRQn = 53, /* CMT0_CMI (CMT0 Compare match) */
+            GPT8_OVF_IRQn = 194, /* GPT_OVF (GPT8 GTCNT overflow (GTPR compare match)) */
             ESC_SYNC0_IRQn = 277, /* ESC_SYNC0 (EtherCAT Sync0 interrupt) */
             ESC_SYNC1_IRQn = 278, /* ESC_SYNC1 (EtherCAT Sync1 interrupt) */
             ESC_CAT_IRQn = 279, /* ESC_CAT (EtherCAT interrupt) */
@@ -57,6 +69,12 @@
             SCI0_RXI_IRQn = 289, /* SCI0_RXI (SCI0 Receive data full) */
             SCI0_TXI_IRQn = 290, /* SCI0_TXI (SCI0 Transmit data empty) */
             SCI0_TEI_IRQn = 291, /* SCI0_TEI (SCI0 Transmit end) */
+            CAN_RXF_IRQn = 316, /* CAN_RXF (CANFD RX FIFO interrupt) */
+            CAN_GLERR_IRQn = 317, /* CAN_GLERR (CANFD Global error interrupt) */
+            CAN0_TX_IRQn = 318, /* CAN0_TX (CANFD0 Channel TX interrupt) */
+            CAN0_CHERR_IRQn = 319, /* CAN0_CHERR (CANFD0 Channel CAN error interrupt) */
+            CAN1_TX_IRQn = 321, /* CAN1_TX (CANFD1 Channel TX interrupt) */
+            CAN1_CHERR_IRQn = 322, /* CAN1_CHERR (CANFD1 Channel CAN error interrupt) */
             SHARED_PERIPHERAL_INTERRUPTS_MAX_ENTRIES = BSP_VECTOR_TABLE_MAX_ENTRIES
         } IRQn_Type;
         #endif /* VECTOR_DATA_H */

+ 3 - 0
projects/etherkit_ethercat_eoe/board/Kconfig

@@ -114,6 +114,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_ethernet/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_ethernetip_opener/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_factory/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_modbus_tcpip/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_modbus_uart/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_profinet_pnet/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_usb_pcdc/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/etherkit_usb_pmsc/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

+ 3 - 0
projects/template_project/board/Kconfig

@@ -98,6 +98,9 @@ menu "Hardware Drivers Config"
             select RT_USING_CAN
             select RT_CAN_USING_CANFD
             if BSP_USING_CANFD
+            	config BSP_USING_CAN_RZ
+                    bool "Enabled this option means turning on standard CAN, while disabling it means switching to CANFD."
+                    default n
                 config BSP_USING_CANFD0
                     bool "Enable CANFD0"
                     default n

Некоторые файлы не были показаны из-за большого количества измененных файлов