mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-23 05:23:33 +08:00
imxrt io_timer: remove some fields from io_timers_t and split out channel indexes
IOMUX uses different enumeration from GPIO pin + port, so we cannot use .gpio_out, and add a .gpio_portpin.
This commit is contained in:
@@ -86,26 +86,37 @@
|
|||||||
__EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = {
|
__EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = {
|
||||||
{
|
{
|
||||||
.base = IMXRT_FLEXPWM2_BASE,
|
.base = IMXRT_FLEXPWM2_BASE,
|
||||||
.first_channel_index = 0,
|
|
||||||
.last_channel_index = 3,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
.base = IMXRT_FLEXPWM3_BASE,
|
.base = IMXRT_FLEXPWM3_BASE,
|
||||||
.first_channel_index = 4,
|
|
||||||
.last_channel_index = 5,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.base = IMXRT_FLEXPWM4_BASE,
|
.base = IMXRT_FLEXPWM4_BASE,
|
||||||
.first_channel_index = 6,
|
|
||||||
.last_channel_index = 7,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__EXPORT const io_timers_channel_mapping_t io_timers_channel_mapping = {
|
||||||
|
.element = {
|
||||||
|
{
|
||||||
|
.first_channel_index = 0,
|
||||||
|
.channel_count = 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first_channel_index = 4,
|
||||||
|
.channel_count = 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.first_channel_index = 6,
|
||||||
|
.channel_count = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
__EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
__EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
||||||
{
|
{
|
||||||
/* FMU_CH1 : GPIO_B0_06 GPIO2 Pin 6 FLEXPWM2_PWMA0 */
|
/* FMU_CH1 : GPIO_B0_06 GPIO2 Pin 6 FLEXPWM2_PWMA0 */
|
||||||
.gpio_out = PIN_FLEXPWM2_PWMA00,
|
.gpio_out = PIN_FLEXPWM2_PWMA00,
|
||||||
|
.gpio_portpin = GPIO_PORT2 | GPIO_PIN6,
|
||||||
.timer_index = 0,
|
.timer_index = 0,
|
||||||
.val_offset = PWMA_VAL,
|
.val_offset = PWMA_VAL,
|
||||||
.sub_module = SM0,
|
.sub_module = SM0,
|
||||||
@@ -115,6 +126,7 @@ __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
|||||||
{
|
{
|
||||||
/* FMU_CH2 : GPIO_EMC_08 GPIO4 Pin 8 FLEXPWM2_PWMA1 */
|
/* FMU_CH2 : GPIO_EMC_08 GPIO4 Pin 8 FLEXPWM2_PWMA1 */
|
||||||
.gpio_out = PIN_FLEXPWM2_PWMA01,
|
.gpio_out = PIN_FLEXPWM2_PWMA01,
|
||||||
|
.gpio_portpin = GPIO_PORT4 | GPIO_PIN8,
|
||||||
.timer_index = 0,
|
.timer_index = 0,
|
||||||
.val_offset = PWMA_VAL,
|
.val_offset = PWMA_VAL,
|
||||||
.sub_module = SM1,
|
.sub_module = SM1,
|
||||||
@@ -124,6 +136,7 @@ __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
|||||||
{
|
{
|
||||||
/* FMU_CH3 : GPIO_EMC_10 GPIO4 Pin 10 FLEXPWM2_PWMA2 */
|
/* FMU_CH3 : GPIO_EMC_10 GPIO4 Pin 10 FLEXPWM2_PWMA2 */
|
||||||
.gpio_out = PIN_FLEXPWM2_PWMA02,
|
.gpio_out = PIN_FLEXPWM2_PWMA02,
|
||||||
|
.gpio_portpin = GPIO_PORT4 | GPIO_PIN10,
|
||||||
.timer_index = 0,
|
.timer_index = 0,
|
||||||
.val_offset = PWMA_VAL,
|
.val_offset = PWMA_VAL,
|
||||||
.sub_module = SM2,
|
.sub_module = SM2,
|
||||||
@@ -133,6 +146,7 @@ __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
|||||||
{
|
{
|
||||||
/* FMU_CH4 : GPIO_AD_B0_09 GPIO1 Pin 9 FLEXPWM2_PWMA3 */
|
/* FMU_CH4 : GPIO_AD_B0_09 GPIO1 Pin 9 FLEXPWM2_PWMA3 */
|
||||||
.gpio_out = PIN_FLEXPWM2_PWMA03,
|
.gpio_out = PIN_FLEXPWM2_PWMA03,
|
||||||
|
.gpio_portpin = GPIO_PORT1 | GPIO_PIN9,
|
||||||
.timer_index = 0,
|
.timer_index = 0,
|
||||||
.val_offset = PWMA_VAL,
|
.val_offset = PWMA_VAL,
|
||||||
.sub_module = SM3,
|
.sub_module = SM3,
|
||||||
@@ -142,6 +156,7 @@ __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
|||||||
{
|
{
|
||||||
/* FMU_CH5 : GPIO_EMC_33 GPIO3 Pin 19 FLEXPWM3_PWMA2 */
|
/* FMU_CH5 : GPIO_EMC_33 GPIO3 Pin 19 FLEXPWM3_PWMA2 */
|
||||||
.gpio_out = PIN_FLEXPWM3_PWMA02,
|
.gpio_out = PIN_FLEXPWM3_PWMA02,
|
||||||
|
.gpio_portpin = GPIO_PORT3 | GPIO_PIN19,
|
||||||
.timer_index = 1,
|
.timer_index = 1,
|
||||||
.val_offset = PWMA_VAL,
|
.val_offset = PWMA_VAL,
|
||||||
.sub_module = SM2,
|
.sub_module = SM2,
|
||||||
@@ -150,6 +165,7 @@ __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
|||||||
{
|
{
|
||||||
/* FMU_CH6 : GPIO_EMC_30 GPIO4 Pin 30 FLEXPWM3_PWMB0 */
|
/* FMU_CH6 : GPIO_EMC_30 GPIO4 Pin 30 FLEXPWM3_PWMB0 */
|
||||||
.gpio_out = PIN_FLEXPWM3_PWMB00,
|
.gpio_out = PIN_FLEXPWM3_PWMB00,
|
||||||
|
.gpio_portpin = GPIO_PORT4 | GPIO_PIN30,
|
||||||
.timer_index = 1,
|
.timer_index = 1,
|
||||||
.val_offset = PWMB_VAL,
|
.val_offset = PWMB_VAL,
|
||||||
.sub_module = SM0,
|
.sub_module = SM0,
|
||||||
@@ -160,6 +176,7 @@ __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
|||||||
{
|
{
|
||||||
/* FMU_CH7 : GPIO_EMC_04 GPIO4 Pin 4 FLEXPWM4_PWMA2 */
|
/* FMU_CH7 : GPIO_EMC_04 GPIO4 Pin 4 FLEXPWM4_PWMA2 */
|
||||||
.gpio_out = PIN_FLEXPWM4_PWMA02,
|
.gpio_out = PIN_FLEXPWM4_PWMA02,
|
||||||
|
.gpio_portpin = GPIO_PORT4 | GPIO_PIN4,
|
||||||
.timer_index = 2,
|
.timer_index = 2,
|
||||||
.val_offset = PWMA_VAL,
|
.val_offset = PWMA_VAL,
|
||||||
.sub_module = SM2,
|
.sub_module = SM2,
|
||||||
@@ -169,6 +186,7 @@ __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
|||||||
{
|
{
|
||||||
/* FMU_CH8 : GPIO_EMC_01 GPIO4 Pin 1 FLEXPWM4_PWMB0 */
|
/* FMU_CH8 : GPIO_EMC_01 GPIO4 Pin 1 FLEXPWM4_PWMB0 */
|
||||||
.gpio_out = PIN_FLEXPWM4_PWMB00,
|
.gpio_out = PIN_FLEXPWM4_PWMB00,
|
||||||
|
.gpio_portpin = GPIO_PORT4 | GPIO_PIN1,
|
||||||
.timer_index = 2,
|
.timer_index = 2,
|
||||||
.val_offset = PWMB_VAL,
|
.val_offset = PWMB_VAL,
|
||||||
.sub_module = SM0,
|
.sub_module = SM0,
|
||||||
|
|||||||
@@ -77,15 +77,23 @@ typedef struct io_timers_t {
|
|||||||
uint32_t clock_register; /* SIM_SCGCn */
|
uint32_t clock_register; /* SIM_SCGCn */
|
||||||
uint32_t clock_bit; /* SIM_SCGCn bit pos */
|
uint32_t clock_bit; /* SIM_SCGCn bit pos */
|
||||||
uint32_t vectorno; /* IRQ number */
|
uint32_t vectorno; /* IRQ number */
|
||||||
uint32_t first_channel_index; /* 0 based index in timer_io_channels */
|
|
||||||
uint32_t last_channel_index; /* 0 based index in timer_io_channels */
|
|
||||||
xcpt_t handler;
|
|
||||||
} io_timers_t;
|
} io_timers_t;
|
||||||
|
|
||||||
|
typedef struct io_timers_channel_mapping_element_t {
|
||||||
|
uint32_t first_channel_index;
|
||||||
|
uint32_t channel_count;
|
||||||
|
} io_timers_channel_mapping_element_t;
|
||||||
|
|
||||||
|
/* mapping for each io_timers to timer_io_channels */
|
||||||
|
typedef struct io_timers_channel_mapping_t {
|
||||||
|
io_timers_channel_mapping_element_t element[MAX_IO_TIMERS];
|
||||||
|
} io_timers_channel_mapping_t;
|
||||||
|
|
||||||
/* array of channels in logical order */
|
/* array of channels in logical order */
|
||||||
typedef struct timer_io_channels_t {
|
typedef struct timer_io_channels_t {
|
||||||
uint32_t gpio_out; /* The timer valn_offset GPIO for PWM */
|
uint32_t gpio_out; /* The timer valn_offset GPIO for PWM */
|
||||||
uint32_t gpio_in; /* The timer valn_offset GPIO for Capture */
|
uint32_t gpio_in; /* The timer valn_offset GPIO for Capture */
|
||||||
|
uint32_t gpio_portpin; /* The GPIO Port + Pin (e.g. GPIO_PORT2 | GPIO_PIN6) */
|
||||||
uint8_t timer_index; /* 0 based index in the io_timers_t table */
|
uint8_t timer_index; /* 0 based index in the io_timers_t table */
|
||||||
uint8_t val_offset; /* IMXRT_FLEXPWM_SM0VAL3_OFFSET or IMXRT_FLEXPWM_SM0VAL5_OFFSET */
|
uint8_t val_offset; /* IMXRT_FLEXPWM_SM0VAL3_OFFSET or IMXRT_FLEXPWM_SM0VAL5_OFFSET */
|
||||||
uint8_t sub_module; /* 0 based sub module offset */
|
uint8_t sub_module; /* 0 based sub module offset */
|
||||||
@@ -109,16 +117,13 @@ typedef void (*channel_handler_t)(void *context, const io_timers_t *timer, uint3
|
|||||||
|
|
||||||
/* supplied by board-specific code */
|
/* supplied by board-specific code */
|
||||||
__EXPORT extern const io_timers_t io_timers[MAX_IO_TIMERS];
|
__EXPORT extern const io_timers_t io_timers[MAX_IO_TIMERS];
|
||||||
|
__EXPORT extern const io_timers_channel_mapping_t io_timers_channel_mapping;
|
||||||
__EXPORT extern const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS];
|
__EXPORT extern const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS];
|
||||||
|
|
||||||
__EXPORT extern const io_timers_t led_pwm_timers[MAX_LED_TIMERS];
|
__EXPORT extern const io_timers_t led_pwm_timers[MAX_LED_TIMERS];
|
||||||
__EXPORT extern const timer_io_channels_t led_pwm_channels[MAX_TIMER_LED_CHANNELS];
|
__EXPORT extern const timer_io_channels_t led_pwm_channels[MAX_TIMER_LED_CHANNELS];
|
||||||
|
|
||||||
__EXPORT extern io_timer_channel_allocation_t allocations[IOTimerChanModeSize];
|
__EXPORT extern io_timer_channel_allocation_t allocations[IOTimerChanModeSize];
|
||||||
__EXPORT int io_timer_handler0(int irq, void *context, void *arg);
|
|
||||||
__EXPORT int io_timer_handler1(int irq, void *context, void *arg);
|
|
||||||
__EXPORT int io_timer_handler2(int irq, void *context, void *arg);
|
|
||||||
__EXPORT int io_timer_handler3(int irq, void *context, void *arg);
|
|
||||||
|
|
||||||
__EXPORT int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
|
__EXPORT int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
|
||||||
channel_handler_t channel_handler, void *context);
|
channel_handler_t channel_handler, void *context);
|
||||||
@@ -139,4 +144,15 @@ __EXPORT int io_timer_get_channel_mode(unsigned channel);
|
|||||||
__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode);
|
__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode);
|
||||||
__EXPORT extern void io_timer_trigger(void);
|
__EXPORT extern void io_timer_trigger(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pin configuration for a specific channel, to be used as GPIO output.
|
||||||
|
* 0 is returned if the channel is not valid.
|
||||||
|
*/
|
||||||
|
__EXPORT uint32_t io_timer_channel_get_gpio_output(unsigned channel);
|
||||||
|
/**
|
||||||
|
* Returns the pin configuration for a specific channel, to be used as PWM input.
|
||||||
|
* 0 is returned if the channel is not valid.
|
||||||
|
*/
|
||||||
|
__EXPORT uint32_t io_timer_channel_get_as_pwm_input(unsigned channel);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|||||||
@@ -31,6 +31,10 @@
|
|||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
add_compile_options(
|
||||||
|
-Wno-unused-function
|
||||||
|
) # TODO: remove once io_timer_handlerX are used
|
||||||
|
|
||||||
px4_add_library(arch_io_pins
|
px4_add_library(arch_io_pins
|
||||||
io_timer.c
|
io_timer.c
|
||||||
pwm_servo.c
|
pwm_servo.c
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* @file drv_io_timer.c
|
* @file io_timer.c
|
||||||
*
|
*
|
||||||
* Servo driver supporting PWM servos connected to imxrt FLEXPWM blocks.
|
* Servo driver supporting PWM servos connected to imxrt FLEXPWM blocks.
|
||||||
*/
|
*/
|
||||||
@@ -62,6 +62,15 @@
|
|||||||
#include "hardware/imxrt_flexpwm.h"
|
#include "hardware/imxrt_flexpwm.h"
|
||||||
#include "imxrt_periphclks.h"
|
#include "imxrt_periphclks.h"
|
||||||
|
|
||||||
|
static int io_timer_handler0(int irq, void *context, void *arg);
|
||||||
|
static int io_timer_handler1(int irq, void *context, void *arg);
|
||||||
|
static int io_timer_handler2(int irq, void *context, void *arg);
|
||||||
|
static int io_timer_handler3(int irq, void *context, void *arg);
|
||||||
|
static int io_timer_handler4(int irq, void *context, void *arg);
|
||||||
|
static int io_timer_handler5(int irq, void *context, void *arg);
|
||||||
|
static int io_timer_handler6(int irq, void *context, void *arg);
|
||||||
|
static int io_timer_handler7(int irq, void *context, void *arg);
|
||||||
|
|
||||||
#if !defined(BOARD_PWM_FREQ)
|
#if !defined(BOARD_PWM_FREQ)
|
||||||
#define BOARD_PWM_FREQ 1000000
|
#define BOARD_PWM_FREQ 1000000
|
||||||
#endif
|
#endif
|
||||||
@@ -169,26 +178,39 @@ static int io_timer_handler(uint16_t timer_index)
|
|||||||
|
|
||||||
int io_timer_handler0(int irq, void *context, void *arg)
|
int io_timer_handler0(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
return io_timer_handler(0);
|
return io_timer_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int io_timer_handler1(int irq, void *context, void *arg)
|
int io_timer_handler1(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
return io_timer_handler(1);
|
return io_timer_handler(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int io_timer_handler2(int irq, void *context, void *arg)
|
int io_timer_handler2(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
return io_timer_handler(2);
|
return io_timer_handler(2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int io_timer_handler3(int irq, void *context, void *arg)
|
int io_timer_handler3(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
return io_timer_handler(3);
|
return io_timer_handler(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int io_timer_handler4(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
return io_timer_handler(4);
|
||||||
|
}
|
||||||
|
int io_timer_handler5(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
return io_timer_handler(5);
|
||||||
|
}
|
||||||
|
int io_timer_handler6(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
return io_timer_handler(6);
|
||||||
|
}
|
||||||
|
int io_timer_handler7(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
return io_timer_handler(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int is_timer_uninitalized(unsigned timer)
|
static inline int is_timer_uninitalized(unsigned timer)
|
||||||
@@ -247,6 +269,26 @@ int io_timer_validate_channel_index(unsigned channel)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t io_timer_channel_get_gpio_output(unsigned channel)
|
||||||
|
{
|
||||||
|
if (io_timer_validate_channel_index(channel) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return timer_io_channels[channel].gpio_portpin | (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP
|
||||||
|
| IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t io_timer_channel_get_as_pwm_input(unsigned channel)
|
||||||
|
{
|
||||||
|
if (io_timer_validate_channel_index(channel) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return timer_io_channels[channel].gpio_in;
|
||||||
|
}
|
||||||
|
|
||||||
int io_timer_get_mode_channels(io_timer_channel_mode_t mode)
|
int io_timer_get_mode_channels(io_timer_channel_mode_t mode)
|
||||||
{
|
{
|
||||||
if (mode < IOTimerChanModeSize) {
|
if (mode < IOTimerChanModeSize) {
|
||||||
@@ -409,8 +451,10 @@ void io_timer_trigger(void)
|
|||||||
action_cache[actions].base = io_timers[timer].base;
|
action_cache[actions].base = io_timers[timer].base;
|
||||||
|
|
||||||
if (action_cache[actions].base) {
|
if (action_cache[actions].base) {
|
||||||
for (uint32_t channel = io_timers[timer].first_channel_index;
|
uint32_t first_channel_index = io_timers_channel_mapping.element[timer].first_channel_index;
|
||||||
channel <= io_timers[timer].last_channel_index; channel++) {
|
uint32_t last_channel_index = first_channel_index + io_timers_channel_mapping.element[timer].channel_count;
|
||||||
|
|
||||||
|
for (uint32_t channel = first_channel_index; channel < last_channel_index; channel++) {
|
||||||
mask = get_channel_mask(channel);
|
mask = get_channel_mask(channel);
|
||||||
|
|
||||||
if (oneshots & mask) {
|
if (oneshots & mask) {
|
||||||
@@ -467,8 +511,10 @@ int io_timer_init_timer(unsigned timer)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t chan = io_timers[timer].first_channel_index;
|
uint32_t first_channel_index = io_timers_channel_mapping.element[timer].first_channel_index;
|
||||||
chan <= io_timers[timer].last_channel_index; chan++) {
|
uint32_t last_channel_index = first_channel_index + io_timers_channel_mapping.element[timer].channel_count;
|
||||||
|
|
||||||
|
for (uint32_t chan = first_channel_index; chan < last_channel_index; chan++) {
|
||||||
|
|
||||||
/* Clear all Faults */
|
/* Clear all Faults */
|
||||||
rFSTS0(timer) = FSTS_FFLAG_MASK;
|
rFSTS0(timer) = FSTS_FFLAG_MASK;
|
||||||
|
|||||||
Reference in New Issue
Block a user