Преглед изворни кода

add pulse encoder porting to imxrt1052 (#4372)

LeeChunHei пре 3 година
родитељ
комит
cd72ef6ecb

+ 7 - 0
bsp/imxrt/libraries/MIMXRT1050/SConscript

@@ -75,6 +75,13 @@ if GetDepend(['BSP_USING_DMA']):
     src += ['MIMXRT1052/drivers/fsl_lpuart_edma.c']
     if GetDepend(['BSP_USING_SPI']):
         src += ['MIMXRT1052/drivers/fsl_lpspi_edma.c']
+    
+if GetDepend(['BSP_USING_PULSE_ENCODER']):
+    src += ['MIMXRT1052/drivers/fsl_enc.c']
+
+#Adding this as XBAR is used in pin mux
+src += ['MIMXRT1052/drivers/fsl_xbara.c']
+src += ['MIMXRT1052/drivers/fsl_xbarb.c']
 
 if rtconfig.CROSS_TOOL == 'gcc':
     group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, ASFLAGS = '$ASFLAGS -D __STARTUP_CLEAR_BSS')

+ 3 - 0
bsp/imxrt/libraries/drivers/SConscript

@@ -63,6 +63,9 @@ if GetDepend('BSP_USING_USB_DEVICE'):
     src += Glob('usb/phy/*.c')
     CPPDEFINES += ['ENDIANNESS']
     
+if GetDepend('BSP_USING_PULSE_ENCODER'):
+    src += ['drv_pulse_encoder.c']
+
 path =  [cwd,cwd + '/config']
 
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES=CPPDEFINES)

+ 160 - 0
bsp/imxrt/libraries/drivers/drv_pulse_encoder.c

@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-08-23     balanceTWK   first version
+ * 2021-01-19     Leslie Lee   port to imxrt series
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#ifdef BSP_USING_PULSE_ENCODER
+
+#include "fsl_common.h"
+#include "fsl_enc.h"
+
+#define LOG_TAG             "drv.pulse_encoder"
+#include <drv_log.h>
+
+#if !defined(BSP_USING_PULSE_ENCODER1) && !defined(BSP_USING_PULSE_ENCODER2) && !defined(BSP_USING_PULSE_ENCODER3) \
+    && !defined(BSP_USING_PULSE_ENCODER4)
+    #error "Please define at least one BSP_USING_PULSE_ENCODERx"
+    /* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
+#elif (defined(BSP_USING_PULSE_ENCODER2) || defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1015_SERIES)
+    #error "IMXRT1015 had only one quadrature decoder module"
+#elif (defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1020_SERIES)
+    #error "IMXRT1020 had only two quadrature decoder module"
+#endif
+
+enum
+{
+#ifdef BSP_USING_PULSE_ENCODER1
+    PULSE_ENCODER1_INDEX,
+#endif
+#ifdef BSP_USING_PULSE_ENCODER2
+    PULSE_ENCODER2_INDEX,
+#endif
+#ifdef BSP_USING_PULSE_ENCODER3
+    PULSE_ENCODER3_INDEX,
+#endif
+#ifdef BSP_USING_PULSE_ENCODER4
+    PULSE_ENCODER4_INDEX,
+#endif
+};
+
+struct imxrt_pulse_encoder_device
+{
+    struct rt_pulse_encoder_device pulse_encoder;
+    ENC_Type *base;
+    char *name;
+};
+typedef struct imxrt_pulse_encoder_device imxrt_pulse_enccoder_device_t;
+
+static imxrt_pulse_enccoder_device_t imxrt_pulse_encoder_obj[] =
+{
+#ifdef BSP_USING_PULSE_ENCODER1
+    {
+       .base            = ENC1,
+       .name            = "pulse1"
+    },
+#endif
+#ifdef BSP_USING_PULSE_ENCODER2
+    {
+       .base            = ENC2,
+       .name            = "pulse2"
+    },
+#endif
+#ifdef BSP_USING_PULSE_ENCODER3
+    {
+       .base            = ENC3,
+       .name            = "pulse3"
+    },
+#endif
+#ifdef BSP_USING_PULSE_ENCODER4
+    {
+       .base            = ENC4,
+       .name            = "pulse4"
+    },
+#endif
+};
+
+
+
+rt_err_t pulse_encoder_init(struct rt_pulse_encoder_device *pulse_encoder)
+{
+    ENC_Type *base = ((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base;
+    enc_config_t enc_config;
+    ENC_GetDefaultConfig(&enc_config);
+    ENC_Init(base, &enc_config);
+    ENC_DoSoftwareLoadInitialPositionValue(base);  /* Update the position counter with initial value. */
+    return RT_EOK;
+}
+
+rt_err_t pulse_encoder_clear_count(struct rt_pulse_encoder_device *pulse_encoder)
+{
+    ENC_SetInitialPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base, 0);
+    return RT_EOK;
+}
+
+rt_int32_t pulse_encoder_get_count(struct rt_pulse_encoder_device *pulse_encoder)
+{
+    return (rt_int32_t)ENC_GetPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
+}
+
+rt_err_t pulse_encoder_control(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args)
+{
+    rt_err_t result;
+
+    result = RT_EOK;
+
+    switch (cmd)
+    {
+    case PULSE_ENCODER_CMD_ENABLE:
+        result = pulse_encoder->ops->init(pulse_encoder);
+        break;
+    case PULSE_ENCODER_CMD_DISABLE:
+        ENC_Deinit(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
+        break;
+    default:
+        result = -RT_ENOSYS;
+        break;
+    }
+
+    return result;
+}
+
+static const struct rt_pulse_encoder_ops _ops =
+{
+    .init = pulse_encoder_init,
+    .get_count = pulse_encoder_get_count,
+    .clear_count = pulse_encoder_clear_count,
+    .control = pulse_encoder_control,
+};
+
+int rt_hw_pulse_encoder_init(void)
+{
+    int i;
+    int result;
+
+    result = RT_EOK;
+    for (i = 0; i < sizeof(imxrt_pulse_encoder_obj) / sizeof(imxrt_pulse_encoder_obj[0]); i++)
+    {
+        imxrt_pulse_encoder_obj[i].pulse_encoder.type = AB_PHASE_PULSE_ENCODER;
+        imxrt_pulse_encoder_obj[i].pulse_encoder.ops = &_ops;
+        imxrt_pulse_encoder_obj[i].pulse_encoder.parent.user_data = &(imxrt_pulse_encoder_obj[i]);
+
+        if (rt_device_pulse_encoder_register(&imxrt_pulse_encoder_obj[i].pulse_encoder, imxrt_pulse_encoder_obj[i].name, &imxrt_pulse_encoder_obj[i]) != RT_EOK)
+        {
+            LOG_E("%s register failed", imxrt_pulse_encoder_obj[i].name);
+            result = -RT_ERROR;
+        }
+    }
+
+    return result;
+}
+INIT_BOARD_EXPORT(rt_hw_pulse_encoder_init);
+
+#endif