add pulse encoder porting to imxrt1052 (#4372)

This commit is contained in:
LeeChunHei 2022-01-24 14:22:48 +08:00 committed by GitHub
parent 0f6e2bbf27
commit cd72ef6ecb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 170 additions and 0 deletions

View File

@ -76,6 +76,13 @@ if GetDepend(['BSP_USING_DMA']):
if GetDepend(['BSP_USING_SPI']): if GetDepend(['BSP_USING_SPI']):
src += ['MIMXRT1052/drivers/fsl_lpspi_edma.c'] 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': if rtconfig.CROSS_TOOL == 'gcc':
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, ASFLAGS = '$ASFLAGS -D __STARTUP_CLEAR_BSS') group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, ASFLAGS = '$ASFLAGS -D __STARTUP_CLEAR_BSS')
else: else:

View File

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

View File

@ -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