forked from Archive/PX4-Autopilot
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:
parent
d74d094940
commit
8cd9afc19a
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue