Skip to content

Commit

Permalink
imxrt io_timer: remove some fields from io_timers_t and split out cha…
Browse files Browse the repository at this point in the history
…nnel indexes

IOMUX uses different enumeration from GPIO pin + port, so we cannot use
.gpio_out, and add a .gpio_portpin.
  • Loading branch information
bkueng authored and davids5 committed Feb 13, 2020
1 parent d74d094 commit 8cd9afc
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 23 deletions.
32 changes: 25 additions & 7 deletions boards/nxp/fmurt1062-v1/src/timer_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
30 changes: 23 additions & 7 deletions platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand All @@ -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
4 changes: 4 additions & 0 deletions platforms/nuttx/src/px4/nxp/imxrt/io_pins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
64 changes: 55 additions & 9 deletions platforms/nuttx/src/px4/nxp/imxrt/io_pins/io_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
*
****************************************************************************/

/*
* @file drv_io_timer.c
/**
* @file io_timer.c
*
* Servo driver supporting PWM servos connected to imxrt FLEXPWM blocks.
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 8cd9afc

Please sign in to comment.