diff --git a/boards/nxp/fmurt1062-v1/src/timer_config.c b/boards/nxp/fmurt1062-v1/src/timer_config.c index e9d0c5e389..43e50a4664 100644 --- a/boards/nxp/fmurt1062-v1/src/timer_config.c +++ b/boards/nxp/fmurt1062-v1/src/timer_config.c @@ -86,26 +86,37 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { { .base = IMXRT_FLEXPWM2_BASE, - .first_channel_index = 0, - .last_channel_index = 3, }, - { .base = IMXRT_FLEXPWM3_BASE, - .first_channel_index = 4, - .last_channel_index = 5, }, { .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] = { { /* FMU_CH1 : GPIO_B0_06 GPIO2 Pin 6 FLEXPWM2_PWMA0 */ .gpio_out = PIN_FLEXPWM2_PWMA00, + .gpio_portpin = GPIO_PORT2 | GPIO_PIN6, .timer_index = 0, .val_offset = PWMA_VAL, .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 */ .gpio_out = PIN_FLEXPWM2_PWMA01, + .gpio_portpin = GPIO_PORT4 | GPIO_PIN8, .timer_index = 0, .val_offset = PWMA_VAL, .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 */ .gpio_out = PIN_FLEXPWM2_PWMA02, + .gpio_portpin = GPIO_PORT4 | GPIO_PIN10, .timer_index = 0, .val_offset = PWMA_VAL, .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 */ .gpio_out = PIN_FLEXPWM2_PWMA03, + .gpio_portpin = GPIO_PORT1 | GPIO_PIN9, .timer_index = 0, .val_offset = PWMA_VAL, .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 */ .gpio_out = PIN_FLEXPWM3_PWMA02, + .gpio_portpin = GPIO_PORT3 | GPIO_PIN19, .timer_index = 1, .val_offset = PWMA_VAL, .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 */ .gpio_out = PIN_FLEXPWM3_PWMB00, + .gpio_portpin = GPIO_PORT4 | GPIO_PIN30, .timer_index = 1, .val_offset = PWMB_VAL, .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 */ .gpio_out = PIN_FLEXPWM4_PWMA02, + .gpio_portpin = GPIO_PORT4 | GPIO_PIN4, .timer_index = 2, .val_offset = PWMA_VAL, .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 */ .gpio_out = PIN_FLEXPWM4_PWMB00, + .gpio_portpin = GPIO_PORT4 | GPIO_PIN1, .timer_index = 2, .val_offset = PWMB_VAL, .sub_module = SM0, diff --git a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer.h b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer.h index d8ebd7c9ef..19c473dacd 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer.h +++ b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer.h @@ -77,15 +77,23 @@ typedef struct io_timers_t { uint32_t clock_register; /* SIM_SCGCn */ uint32_t clock_bit; /* SIM_SCGCn bit pos */ 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; +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 */ typedef struct timer_io_channels_t { 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_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 val_offset; /* IMXRT_FLEXPWM_SM0VAL3_OFFSET or IMXRT_FLEXPWM_SM0VAL5_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 */ __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 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 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, 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 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 diff --git a/platforms/nuttx/src/px4/nxp/imxrt/io_pins/CMakeLists.txt b/platforms/nuttx/src/px4/nxp/imxrt/io_pins/CMakeLists.txt index 401bf06ef5..a048ebfa8e 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/io_pins/CMakeLists.txt +++ b/platforms/nuttx/src/px4/nxp/imxrt/io_pins/CMakeLists.txt @@ -31,6 +31,10 @@ # ############################################################################ +add_compile_options( + -Wno-unused-function + ) # TODO: remove once io_timer_handlerX are used + px4_add_library(arch_io_pins io_timer.c pwm_servo.c diff --git a/platforms/nuttx/src/px4/nxp/imxrt/io_pins/io_timer.c b/platforms/nuttx/src/px4/nxp/imxrt/io_pins/io_timer.c index 271d2e6338..e7de2d859f 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/io_pins/io_timer.c +++ b/platforms/nuttx/src/px4/nxp/imxrt/io_pins/io_timer.c @@ -31,8 +31,8 @@ * ****************************************************************************/ -/* - * @file drv_io_timer.c +/** + * @file io_timer.c * * Servo driver supporting PWM servos connected to imxrt FLEXPWM blocks. */ @@ -62,6 +62,15 @@ #include "hardware/imxrt_flexpwm.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) #define BOARD_PWM_FREQ 1000000 #endif @@ -169,26 +178,39 @@ static int io_timer_handler(uint16_t timer_index) int io_timer_handler0(int irq, void *context, void *arg) { - return io_timer_handler(0); } int io_timer_handler1(int irq, void *context, void *arg) { return io_timer_handler(1); - } int io_timer_handler2(int irq, void *context, void *arg) { return io_timer_handler(2); - } int io_timer_handler3(int irq, void *context, void *arg) { 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) @@ -247,6 +269,26 @@ int io_timer_validate_channel_index(unsigned channel) 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) { if (mode < IOTimerChanModeSize) { @@ -409,8 +451,10 @@ void io_timer_trigger(void) action_cache[actions].base = io_timers[timer].base; if (action_cache[actions].base) { - for (uint32_t channel = io_timers[timer].first_channel_index; - channel <= io_timers[timer].last_channel_index; channel++) { + uint32_t first_channel_index = io_timers_channel_mapping.element[timer].first_channel_index; + 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); if (oneshots & mask) { @@ -467,8 +511,10 @@ int io_timer_init_timer(unsigned timer) break; } - for (uint32_t chan = io_timers[timer].first_channel_index; - chan <= io_timers[timer].last_channel_index; chan++) { + uint32_t first_channel_index = io_timers_channel_mapping.element[timer].first_channel_index; + 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 */ rFSTS0(timer) = FSTS_FFLAG_MASK;