diff --git a/boards/airmind/mindpx-v2/src/timer_config.c b/boards/airmind/mindpx-v2/src/timer_config.c index 6f9b6fee53..7c0b7025ca 100644 --- a/boards/airmind/mindpx-v2/src/timer_config.c +++ b/boards/airmind/mindpx-v2/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, }, { @@ -66,12 +63,21 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 7, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4 } }; +__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 = 4, + } + } +}; __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { diff --git a/boards/av/x-v1/src/timer_config.c b/boards/av/x-v1/src/timer_config.c index 110e512747..ea51b9837b 100644 --- a/boards/av/x-v1/src/timer_config.c +++ b/boards/av/x-v1/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, }, { @@ -66,9 +63,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM2EN, .clock_freq = STM32_APB1_TIM2_CLKIN, - .first_channel_index = 4, - .last_channel_index = 4, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM2, }, { @@ -76,9 +70,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM8EN, .clock_freq = STM32_APB2_TIM8_CLKIN, - .first_channel_index = 5, - .last_channel_index = 5, - .handler = io_timer_handler2, .vectorno = STM32_IRQ_TIM8CC, }, { @@ -86,9 +77,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM11EN, .clock_freq = STM32_APB2_TIM11_CLKIN, - .first_channel_index = 6, - .last_channel_index = 6, - .handler = io_timer_handler3, .vectorno = STM32_IRQ_TIM11, }, { @@ -96,9 +84,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM10EN, .clock_freq = STM32_APB2_TIM10_CLKIN, - .first_channel_index = 7, - .last_channel_index = 7, - .handler = io_timer_handler4, .vectorno = STM32_IRQ_TIM10, }, // { @@ -106,13 +91,35 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { // .clock_register = STM32_RCC_APB1ENR, // .clock_bit = RCC_APB1ENR_TIM4EN, // .clock_freq = STM32_APB1_TIM4_CLKIN, - // .first_channel_index = 8, - // .last_channel_index = 8, - // .handler = io_timer_handler5, // .vectorno = STM32_IRQ_TIM4, // } }; +__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 = 1, + }, + { + .first_channel_index = 5, + .channel_count = 1, + }, + { + .first_channel_index = 6, + .channel_count = 1, + }, + { + .first_channel_index = 7, + .channel_count = 1, + }, + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH1OUT, diff --git a/boards/bitcraze/crazyflie/src/timer_config.c b/boards/bitcraze/crazyflie/src/timer_config.c index efe84f5ab7..53aa56da72 100644 --- a/boards/bitcraze/crazyflie/src/timer_config.c +++ b/boards/bitcraze/crazyflie/src/timer_config.c @@ -65,9 +65,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM2EN, .clock_freq = TIM2_CLKIN, - .first_channel_index = 0, - .last_channel_index = 2, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM2, }, { @@ -75,12 +72,21 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = TIM4_CLKIN, - .first_channel_index = 3, - .last_channel_index = 3, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, } }; +__EXPORT const io_timers_channel_mapping_t io_timers_channel_mapping = { + .element = { + { + .first_channel_index = 0, + .channel_count = 3, + }, + { + .first_channel_index = 3, + .channel_count = 1, + } + } +}; __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { diff --git a/boards/holybro/durandal-v1/src/timer_config.c b/boards/holybro/durandal-v1/src/timer_config.c index 92379e4080..8385855b48 100644 --- a/boards/holybro/durandal-v1/src/timer_config.c +++ b/boards/holybro/durandal-v1/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIMCC, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_DMA12_TIM1UP_0, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, { @@ -72,19 +67,27 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1LENR, .clock_bit = RCC_APB1LENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 4, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_DMA12_TIM4UP_0, - .start_ccr_register = TIM_DMABASE_CCR2, - .channels_number = 1u /* CCR2 */ } }, }; +__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 = 1, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/holybro/kakutef7/src/timer_config.c b/boards/holybro/kakutef7/src/timer_config.c index ce511a0003..13d7d832ff 100644 --- a/boards/holybro/kakutef7/src/timer_config.c +++ b/boards/holybro/kakutef7/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM3EN, .clock_freq = STM32_APB1_TIM3_CLKIN, - .first_channel_index = 0, - .last_channel_index = 1, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM3, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM3_UP, - .start_ccr_register = TIM_DMABASE_CCR3, - .channels_number = 2u /* CCR3 and CCR4 */ } }, { @@ -72,15 +67,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 2, - .last_channel_index = 3, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 2u /* CCR1 and CCR2 */ } }, { @@ -88,15 +78,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM8EN, .clock_freq = STM32_APB2_TIM8_CLKIN, - .first_channel_index = 4, - .last_channel_index = 4, - .handler = io_timer_handler2, .vectorno = STM32_IRQ_TIM8CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM8_UP, - .start_ccr_register = TIM_DMABASE_CCR4, - .channels_number = 1u /* CCR4 */ } }, { @@ -104,19 +89,35 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM5EN, .clock_freq = STM32_APB1_TIM5_CLKIN, - .first_channel_index = 5, - .last_channel_index = 5, - .handler = io_timer_handler3, .vectorno = STM32_IRQ_TIM5, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM5_UP_2, - .start_ccr_register = TIM_DMABASE_CCR4, - .channels_number = 1u /* CCR4 */ } } }; +__EXPORT const io_timers_channel_mapping_t io_timers_channel_mapping = { + .element = { + { + .first_channel_index = 0, + .channel_count = 2, + }, + { + .first_channel_index = 2, + .channel_count = 2, + }, + { + .first_channel_index = 4, + .channel_count = 1, + }, + { + .first_channel_index = 5, + .channel_count = 1, + }, + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM3_CH3OUT, diff --git a/boards/intel/aerofc-v1/src/timer_config.c b/boards/intel/aerofc-v1/src/timer_config.c index 887e5013e9..09b6260707 100644 --- a/boards/intel/aerofc-v1/src/timer_config.c +++ b/boards/intel/aerofc-v1/src/timer_config.c @@ -58,6 +58,8 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { }; // Invalidate all channels (timer_channel == 0): we don't have any __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { }; +__EXPORT const io_timers_channel_mapping_t io_timers_channel_mapping = { }; + // Invalidate all timers (base == 0): we don't have any __EXPORT const struct io_timers_t led_pwm_timers[MAX_LED_TIMERS] = { }; diff --git a/boards/modalai/fc-v1/src/timer_config.c b/boards/modalai/fc-v1/src/timer_config.c index cc05d34010..30d901bb46 100644 --- a/boards/modalai/fc-v1/src/timer_config.c +++ b/boards/modalai/fc-v1/src/timer_config.c @@ -71,15 +71,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, { @@ -87,13 +82,23 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, } }; +__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 = 4, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/mro/ctrl-zero-f7/src/timer_config.c b/boards/mro/ctrl-zero-f7/src/timer_config.c index bc6a90aed9..a34404153c 100644 --- a/boards/mro/ctrl-zero-f7/src/timer_config.c +++ b/boards/mro/ctrl-zero-f7/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, }, { @@ -66,9 +63,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, }, { @@ -76,13 +70,27 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM8EN, .clock_freq = STM32_APB2_TIM8_CLKIN, - .first_channel_index = 6, - .last_channel_index = 7, - .handler = io_timer_handler2, .vectorno = STM32_IRQ_TIM8UP, } }; +__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] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/mro/x21-777/src/timer_config.c b/boards/mro/x21-777/src/timer_config.c index eb64af1247..dc7e0a9764 100644 --- a/boards/mro/x21-777/src/timer_config.c +++ b/boards/mro/x21-777/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, }, { @@ -66,13 +63,23 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4 } }; +__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, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/mro/x21/src/timer_config.c b/boards/mro/x21/src/timer_config.c index 3935158734..12223d4d54 100644 --- a/boards/mro/x21/src/timer_config.c +++ b/boards/mro/x21/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, }, @@ -67,13 +64,23 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4 } }; +__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, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/nxp/fmuk66-v3/src/timer_config.c b/boards/nxp/fmuk66-v3/src/timer_config.c index f56a0956da..5120bf9919 100644 --- a/boards/nxp/fmuk66-v3/src/timer_config.c +++ b/boards/nxp/fmuk66-v3/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .base = KINETIS_FTM0_BASE, .clock_register = KINETIS_SIM_SCGC6, .clock_bit = SIM_SCGC6_FTM0, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = KINETIS_IRQ_FTM0, }, @@ -66,22 +63,33 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .base = KINETIS_FTM3_BASE, .clock_register = KINETIS_SIM_SCGC3, .clock_bit = SIM_SCGC3_FTM3, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = KINETIS_IRQ_FTM3, }, { .base = KINETIS_FTM2_BASE, .clock_register = KINETIS_SIM_SCGC3, .clock_bit = SIM_SCGC3_FTM2, - .first_channel_index = 6, - .last_channel_index = 7, - .handler = io_timer_handler2, .vectorno = KINETIS_IRQ_FTM2, } }; +__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 = 3, + }, + { + .first_channel_index = 6, + .channel_count = 1, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_FTM0_CH0OUT, // FMU_CH1 @@ -138,8 +146,6 @@ __EXPORT const struct io_timers_t led_pwm_timers[MAX_LED_TIMERS] = { .base = KINETIS_FTM3_BASE, .clock_register = KINETIS_SIM_SCGC3, .clock_bit = SIM_SCGC3_FTM3, - .first_channel_index = 0, - .last_channel_index = 2, .vectorno = 0, }, }; diff --git a/boards/omnibus/f4sd/src/timer_config.c b/boards/omnibus/f4sd/src/timer_config.c index 7b99c523d9..a748602e39 100644 --- a/boards/omnibus/f4sd/src/timer_config.c +++ b/boards/omnibus/f4sd/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM2EN, .clock_freq = STM32_APB1_TIM2_CLKIN, - .first_channel_index = 0, - .last_channel_index = 1, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM2, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM2_UP_1, - .start_ccr_register = TIM_DMABASE_CCR3, - .channels_number = 2u /* CCR3 and CCR4 */ } }, { @@ -72,19 +67,28 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM3EN, .clock_freq = STM32_APB1_TIM3_CLKIN, - .first_channel_index = 2, - .last_channel_index = 3, - .handler = io_timer_handler2, .vectorno = STM32_IRQ_TIM3, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM3_UP, - .start_ccr_register = TIM_DMABASE_CCR3, - .channels_number = 2u /* CCR3 and CCR4 */ } } }; +__EXPORT const io_timers_channel_mapping_t io_timers_channel_mapping = { + .element = { + { + .first_channel_index = 0, + .channel_count = 2, + }, + { + .first_channel_index = 2, + .channel_count = 2, + } + } +}; + + /* * OUTPUTS: * M3 : PA3 : TIM2_CH3 diff --git a/boards/px4/fmu-v2/src/timer_config.c b/boards/px4/fmu-v2/src/timer_config.c index 4b47bd3b5c..67e93ef04c 100644 --- a/boards/px4/fmu-v2/src/timer_config.c +++ b/boards/px4/fmu-v2/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, { @@ -72,15 +67,23 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM4_UP, - .start_ccr_register = TIM_DMABASE_CCR2, - .channels_number = 2u /* CCR2 and CCR3 */ + } + } +}; + +__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, } } }; diff --git a/boards/px4/fmu-v3/src/timer_config.c b/boards/px4/fmu-v3/src/timer_config.c index 4b47bd3b5c..67e93ef04c 100644 --- a/boards/px4/fmu-v3/src/timer_config.c +++ b/boards/px4/fmu-v3/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, { @@ -72,15 +67,23 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM4_UP, - .start_ccr_register = TIM_DMABASE_CCR2, - .channels_number = 2u /* CCR2 and CCR3 */ + } + } +}; + +__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, } } }; diff --git a/boards/px4/fmu-v4/src/timer_config.c b/boards/px4/fmu-v4/src/timer_config.c index f7f1d61ece..198efe9fc2 100644 --- a/boards/px4/fmu-v4/src/timer_config.c +++ b/boards/px4/fmu-v4/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, @@ -73,20 +68,28 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM4_UP, - .start_ccr_register = TIM_DMABASE_CCR2, - .channels_number = 2u // CCR2 and CCR3 } } }; +__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, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/px4/fmu-v4pro/src/timer_config.c b/boards/px4/fmu-v4pro/src/timer_config.c index 9947d27daf..1c65cc92d1 100644 --- a/boards/px4/fmu-v4pro/src/timer_config.c +++ b/boards/px4/fmu-v4pro/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, }, @@ -67,13 +64,23 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, } }; +__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, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/px4/fmu-v5/src/timer_config.c b/boards/px4/fmu-v5/src/timer_config.c index 3fe13aed11..6d6978d06b 100644 --- a/boards/px4/fmu-v5/src/timer_config.c +++ b/boards/px4/fmu-v5/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, { @@ -72,9 +67,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, }, { @@ -82,9 +74,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM12EN, .clock_freq = STM32_APB1_TIM12_CLKIN, - .first_channel_index = 6, - .last_channel_index = 7, - .handler = io_timer_handler2, .vectorno = STM32_IRQ_TIM12, }, { @@ -92,9 +81,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM2EN, .clock_freq = STM32_APB1_TIM2_CLKIN, - .first_channel_index = 8, - .last_channel_index = 10, - .handler = io_timer_handler3, .vectorno = STM32_IRQ_TIM2, }, { @@ -102,13 +88,35 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM9EN, .clock_freq = STM32_APB2_TIM9_CLKIN, - .first_channel_index = 11, - .last_channel_index = 11, - .handler = io_timer_handler4, .vectorno = STM32_IRQ_TIM9, } }; +__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, + }, + { + .first_channel_index = 8, + .channel_count = 3, + }, + { + .first_channel_index = 11, + .channel_count = 1, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, @@ -185,8 +193,6 @@ __EXPORT const struct io_timers_t led_pwm_timers[MAX_LED_TIMERS] = { .clock_bit = RCC_APB1ENR_TIM5EN, .clock_freq = STM32_APB1_TIM5_CLKIN, .vectorno = 0, - .first_channel_index = 0, - .last_channel_index = 2, }, # endif # if defined(BOARD_HAS_LED_PWM) && !defined(BOARD_HAS_CONTROL_STATUS_LEDS) @@ -196,13 +202,6 @@ __EXPORT const struct io_timers_t led_pwm_timers[MAX_LED_TIMERS] = { .clock_bit = RCC_APB1ENR_TIM3EN, .clock_freq = STM32_APB1_TIM3_CLKIN, .vectorno = 0, -# if defined(BOARD_HAS_UI_LED_PWM) - .first_channel_index = 3, - .last_channel_index = 5, -# else - .first_channel_index = 0, - .last_channel_index = 2, -# endif }, # endif }; diff --git a/boards/px4/fmu-v5x/src/timer_config.c b/boards/px4/fmu-v5x/src/timer_config.c index 4b2675775f..d572931a8f 100644 --- a/boards/px4/fmu-v5x/src/timer_config.c +++ b/boards/px4/fmu-v5x/src/timer_config.c @@ -79,15 +79,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, { @@ -95,15 +90,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM4_UP, - .start_ccr_register = TIM_DMABASE_CCR2, - .channels_number = 2u /* CCR2 and CCR3 */ } }, { @@ -111,9 +101,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM12EN, .clock_freq = STM32_APB1_TIM12_CLKIN, - .first_channel_index = 6, - .last_channel_index = 7, - .handler = io_timer_handler2, .vectorno = STM32_IRQ_TIM12, }, { @@ -121,9 +108,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM5EN, .clock_freq = STM32_APB1_TIM5_CLKIN, - .first_channel_index = 8, - .last_channel_index = 10, - .handler = io_timer_handler3, .vectorno = STM32_IRQ_TIM5, }, { @@ -131,13 +115,35 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM2EN, .clock_freq = STM32_APB1_TIM2_CLKIN, - .first_channel_index = 11, - .last_channel_index = 11, - .handler = io_timer_handler4, .vectorno = STM32_IRQ_TIM2, }, }; +__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, + }, + { + .first_channel_index = 8, + .channel_count = 3, + }, + { + .first_channel_index = 11, + .channel_count = 1, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/boards/px4/io-v2/src/timer_config.c b/boards/px4/io-v2/src/timer_config.c index 72968008aa..6fc486c949 100644 --- a/boards/px4/io-v2/src/timer_config.c +++ b/boards/px4/io-v2/src/timer_config.c @@ -56,9 +56,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM2EN, .clock_freq = STM32_APB1_TIM2_CLKIN, - .first_channel_index = 0, - .last_channel_index = 1, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM2, }, { @@ -66,9 +63,6 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM3EN, .clock_freq = STM32_APB1_TIM3_CLKIN, - .first_channel_index = 4, - .last_channel_index = 7, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM3, }, { @@ -76,13 +70,27 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 2, - .last_channel_index = 3, - .handler = io_timer_handler2, .vectorno = STM32_IRQ_TIM4, } }; +__EXPORT const io_timers_channel_mapping_t io_timers_channel_mapping = { + .element = { + { + .first_channel_index = 0, + .channel_count = 2, + }, + { + .first_channel_index = 4, + .channel_count = 4, + }, + { + .first_channel_index = 2, + .channel_count = 2, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM2_CH1OUT, diff --git a/boards/uvify/core/src/timer_config.c b/boards/uvify/core/src/timer_config.c index 32456cca1a..b2e7ad19d9 100644 --- a/boards/uvify/core/src/timer_config.c +++ b/boards/uvify/core/src/timer_config.c @@ -56,15 +56,10 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB2ENR, .clock_bit = RCC_APB2ENR_TIM1EN, .clock_freq = STM32_APB2_TIM1_CLKIN, - .first_channel_index = 0, - .last_channel_index = 3, - .handler = io_timer_handler0, .vectorno = STM32_IRQ_TIM1CC, .dshot = { .dma_base = STM32_DMA2_BASE, .dmamap = DMAMAP_TIM1_UP, - .start_ccr_register = TIM_DMABASE_CCR1, - .channels_number = 4u /* CCR1, CCR2, CCR3 and CCR4 */ } }, @@ -73,20 +68,28 @@ __EXPORT const io_timers_t io_timers[MAX_IO_TIMERS] = { .clock_register = STM32_RCC_APB1ENR, .clock_bit = RCC_APB1ENR_TIM4EN, .clock_freq = STM32_APB1_TIM4_CLKIN, - .first_channel_index = 4, - .last_channel_index = 5, - .handler = io_timer_handler1, .vectorno = STM32_IRQ_TIM4, .dshot = { .dma_base = STM32_DMA1_BASE, .dmamap = DMAMAP_TIM4_UP, - .start_ccr_register = TIM_DMABASE_CCR2, - .channels_number = 2u // CCR2 and CCR3 } } }; +__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, + } + } +}; + __EXPORT const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { { .gpio_out = GPIO_TIM1_CH4OUT, diff --git a/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/io_timer.h b/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/io_timer.h index 5df17d2d31..40052ed9b8 100644 --- a/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/io_timer.h +++ b/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/io_timer.h @@ -82,11 +82,18 @@ 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 channel GPIO for PWM */ @@ -104,16 +111,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); diff --git a/platforms/nuttx/src/px4/nxp/kinetis/io_pins/io_timer.c b/platforms/nuttx/src/px4/nxp/kinetis/io_pins/io_timer.c index b8ffe90684..2485cc0532 100644 --- a/platforms/nuttx/src/px4/nxp/kinetis/io_pins/io_timer.c +++ b/platforms/nuttx/src/px4/nxp/kinetis/io_pins/io_timer.c @@ -62,6 +62,16 @@ #include "hardware/kinetis_sim.h" #include "hardware/kinetis_ftm.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); + /* The FTM pre-scalers are limited to Divide by 2^n where n={1-7} * Therefore we use Y1 at 16 Mhz to drive FTM_CLKIN0 (PCT12) * and use this at a 16Mhz clock for FTM0, FTM2 and FTM3. @@ -184,7 +194,10 @@ static int io_timer_handler(uint16_t timer_index) /* Iterate over the timer_io_channels table */ - for (unsigned chan_index = tmr->first_channel_index; chan_index <= tmr->last_channel_index; chan_index++) { + uint32_t first_channel_index = io_timers_channel_mapping.element[timer_index].first_channel_index; + uint32_t last_channel_index = first_channel_index + io_timers_channel_mapping.element[timer_index].channel_count; + + for (unsigned chan_index = first_channel_index; chan_index < last_channel_index; chan_index++) { uint16_t chan = 1 << chan_index; @@ -216,26 +229,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 validate_timer_index(unsigned timer) @@ -269,17 +295,6 @@ static inline int channels_timer(unsigned channel) return timer_io_channels[channel].timer_index; } -static inline int get_timers_firstchannels(unsigned timer) -{ - int channel = -1; - - if (validate_timer_index(timer) == 0) { - channel = timer_io_channels[io_timers[timer].first_channel_index].timer_channel; - } - - return channel; -} - static uint32_t get_timer_channels(unsigned timer) { uint32_t channels = 0; @@ -290,11 +305,13 @@ static uint32_t get_timer_channels(unsigned timer) } else { if (channels_cache[timer] == 0) { - const io_timers_t *tmr = &io_timers[timer]; /* Gather the channel bits that belong to the timer */ - for (unsigned chan_index = tmr->first_channel_index; chan_index <= tmr->last_channel_index; chan_index++) { + 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 (unsigned chan_index = first_channel_index; chan_index < last_channel_index; chan_index++) { channels |= 1 << chan_index; } @@ -577,10 +594,35 @@ int io_timer_init_timer(unsigned timer) * Note that the timer is left disabled with IRQ subs installed * and active but DEIR bits are not set. */ + xcpt_t handler; - irq_attach(io_timers[timer].vectorno, io_timers[timer].handler, NULL); + switch (timer) { + case 0: handler = io_timer_handler0; break; - up_enable_irq(io_timers[timer].vectorno); + case 1: handler = io_timer_handler1; break; + + case 2: handler = io_timer_handler2; break; + + case 3: handler = io_timer_handler3; break; + + case 4: handler = io_timer_handler4; break; + + case 5: handler = io_timer_handler5; break; + + case 6: handler = io_timer_handler6; break; + + case 7: handler = io_timer_handler7; break; + + default: + handler = NULL; + rv = -EINVAL; + break; + } + + if (handler) { + irq_attach(io_timers[timer].vectorno, handler, NULL); + up_enable_irq(io_timers[timer].vectorno); + } px4_leave_critical_section(flags); } diff --git a/platforms/nuttx/src/px4/nxp/s32k1xx/include/px4_arch/io_timer.h b/platforms/nuttx/src/px4/nxp/s32k1xx/include/px4_arch/io_timer.h index 5df17d2d31..c0f0377d1e 100644 --- a/platforms/nuttx/src/px4/nxp/s32k1xx/include/px4_arch/io_timer.h +++ b/platforms/nuttx/src/px4/nxp/s32k1xx/include/px4_arch/io_timer.h @@ -82,11 +82,18 @@ 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 channel GPIO for PWM */ @@ -104,16 +111,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); @@ -133,5 +137,17 @@ __EXPORT int io_timer_free_channel(unsigned channel); __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/s32k1xx/io_pins/io_timer.c b/platforms/nuttx/src/px4/nxp/s32k1xx/io_pins/io_timer.c index b8ffe90684..393920d39d 100644 --- a/platforms/nuttx/src/px4/nxp/s32k1xx/io_pins/io_timer.c +++ b/platforms/nuttx/src/px4/nxp/s32k1xx/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 Kinetis FTM timer blocks. */ @@ -62,6 +62,16 @@ #include "hardware/kinetis_sim.h" #include "hardware/kinetis_ftm.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); + /* The FTM pre-scalers are limited to Divide by 2^n where n={1-7} * Therefore we use Y1 at 16 Mhz to drive FTM_CLKIN0 (PCT12) * and use this at a 16Mhz clock for FTM0, FTM2 and FTM3. @@ -184,7 +194,10 @@ static int io_timer_handler(uint16_t timer_index) /* Iterate over the timer_io_channels table */ - for (unsigned chan_index = tmr->first_channel_index; chan_index <= tmr->last_channel_index; chan_index++) { + uint32_t first_channel_index = io_timers_channel_mapping.element[timer_index].first_channel_index; + uint32_t last_channel_index = first_channel_index + io_timers_channel_mapping.element[timer_index].channel_count; + + for (unsigned chan_index = first_channel_index; chan_index < last_channel_index; chan_index++) { uint16_t chan = 1 << chan_index; @@ -216,26 +229,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 validate_timer_index(unsigned timer) @@ -269,17 +295,6 @@ static inline int channels_timer(unsigned channel) return timer_io_channels[channel].timer_index; } -static inline int get_timers_firstchannels(unsigned timer) -{ - int channel = -1; - - if (validate_timer_index(timer) == 0) { - channel = timer_io_channels[io_timers[timer].first_channel_index].timer_channel; - } - - return channel; -} - static uint32_t get_timer_channels(unsigned timer) { uint32_t channels = 0; @@ -290,11 +305,13 @@ static uint32_t get_timer_channels(unsigned timer) } else { if (channels_cache[timer] == 0) { - const io_timers_t *tmr = &io_timers[timer]; /* Gather the channel bits that belong to the timer */ - for (unsigned chan_index = tmr->first_channel_index; chan_index <= tmr->last_channel_index; chan_index++) { + 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 (unsigned chan_index = first_channel_index; chan_index < last_channel_index; chan_index++) { channels |= 1 << chan_index; } @@ -345,6 +362,25 @@ 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_out & ~(_PIN_MODE_MASK | _PIN_OPTIONS_MASK)) | GPIO_HIGHDRIVE; +} + +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) { @@ -577,10 +613,35 @@ int io_timer_init_timer(unsigned timer) * Note that the timer is left disabled with IRQ subs installed * and active but DEIR bits are not set. */ + xcpt_t handler; - irq_attach(io_timers[timer].vectorno, io_timers[timer].handler, NULL); + switch (timer) { + case 0: handler = io_timer_handler0; break; - up_enable_irq(io_timers[timer].vectorno); + case 1: handler = io_timer_handler1; break; + + case 2: handler = io_timer_handler2; break; + + case 3: handler = io_timer_handler3; break; + + case 4: handler = io_timer_handler4; break; + + case 5: handler = io_timer_handler5; break; + + case 6: handler = io_timer_handler6; break; + + case 7: handler = io_timer_handler7; break; + + default: + handler = NULL; + rv = -EINVAL; + break; + } + + if (handler) { + irq_attach(io_timers[timer].vectorno, handler, NULL); + up_enable_irq(io_timers[timer].vectorno); + } px4_leave_critical_section(flags); } diff --git a/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c b/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c index 4f91d9ad74..66d53b2f03 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c +++ b/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c @@ -108,7 +108,7 @@ int up_dshot_init(uint32_t channel_mask, unsigned dshot_pwm_freq) #pragma GCC diagnostic ignored "-Wcast-align" dshot_burst_buffer[timer] = (uint32_t *)&dshot_burst_buffer_array[buffer_offset]; #pragma GCC diagnostic pop - buffer_offset += DSHOT_BURST_BUFFER_SIZE(io_timers[timer].dshot.channels_number); + buffer_offset += DSHOT_BURST_BUFFER_SIZE(io_timers_channel_mapping.element[timer].channel_count); if (buffer_offset > sizeof(dshot_burst_buffer_array)) { return -EINVAL; // something is wrong with the board configuration or some other logic @@ -143,8 +143,9 @@ int up_dshot_init(uint32_t channel_mask, unsigned dshot_pwm_freq) for (uint8_t timer_index = 0; (timer_index < DSHOT_TIMERS) && (OK == ret_val); timer_index++) { if (true == dshot_handler[timer_index].init) { - dshot_handler[timer_index].dma_size = io_timers[timer_index].dshot.channels_number * ONE_MOTOR_BUFF_SIZE; - io_timer_set_dshot_mode(timer_index, dshot_pwm_freq, io_timers[timer_index].dshot.channels_number); + dshot_handler[timer_index].dma_size = io_timers_channel_mapping.element[timer_index].channel_count * + ONE_MOTOR_BUFF_SIZE; + io_timer_set_dshot_mode(timer_index, dshot_pwm_freq, io_timers_channel_mapping.element[timer_index].channel_count); dshot_handler[timer_index].dma_handle = stm32_dmachannel(io_timers[timer_index].dshot.dmamap); @@ -165,7 +166,7 @@ void up_dshot_trigger(void) if (true == dshot_handler[timer].init) { - uint8_t motors_number = io_timers[timer].dshot.channels_number; + uint8_t motors_number = io_timers_channel_mapping.element[timer].channel_count; dshot_dmar_data_prepare(timer, first_motor, motors_number); // Flush cache so DMA sees the data diff --git a/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/dshot.h b/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/dshot.h index a539adcfc2..93811a898c 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/dshot.h +++ b/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/dshot.h @@ -59,6 +59,4 @@ typedef struct dshot_conf_t { uint32_t dma_base; uint32_t dmamap; - uint32_t start_ccr_register; - uint8_t channels_number; ///< number of channels/outputs (<=MAX_NUM_CHANNELS_PER_TIMER) } dshot_conf_t; diff --git a/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h b/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h index 61dc74385f..2e10fc9345 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h +++ b/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h @@ -89,12 +89,19 @@ typedef struct io_timers_t { uint32_t clock_bit; uint32_t clock_freq; uint32_t vectorno; - uint32_t first_channel_index; - uint32_t last_channel_index; - xcpt_t handler; dshot_conf_t dshot; } 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; @@ -105,7 +112,6 @@ typedef struct timer_io_channels_t { uint8_t ccr_offset; } timer_io_channels_t; - typedef void (*channel_handler_t)(void *context, const io_timers_t *timer, uint32_t chan_index, const timer_io_channels_t *chan, hrt_abstime isrs_time, uint16_t isrs_rcnt); @@ -113,17 +119,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_handler4(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); diff --git a/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c b/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c index cb5963f16c..ebdb66561b 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c +++ b/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c @@ -59,6 +59,16 @@ #include #include + +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(HAVE_GTIM_CCXNP) #define HW_GTIM_CCER_CC1NP GTIM_CCER_CC1NP #else @@ -182,7 +192,10 @@ static int io_timer_handler(uint16_t timer_index) /* Iterate over the timer_io_channels table */ - for (unsigned chan_index = tmr->first_channel_index; chan_index <= tmr->last_channel_index; chan_index++) { + uint32_t first_channel_index = io_timers_channel_mapping.element[timer_index].first_channel_index; + uint32_t last_channel_index = first_channel_index + io_timers_channel_mapping.element[timer_index].channel_count; + + for (unsigned chan_index = first_channel_index; chan_index < last_channel_index; chan_index++) { uint16_t masks = timer_io_channels[chan_index].masks; @@ -222,32 +235,42 @@ 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 validate_timer_index(unsigned timer) @@ -281,17 +304,6 @@ static inline int channels_timer(unsigned channel) return timer_io_channels[channel].timer_index; } -static inline int get_timers_firstchannels(unsigned timer) -{ - int channel = -1; - - if (validate_timer_index(timer) == 0) { - channel = timer_io_channels[io_timers[timer].first_channel_index].timer_channel; - } - - return channel; -} - static uint32_t get_timer_channels(unsigned timer) { uint32_t channels = 0; @@ -302,11 +314,12 @@ static uint32_t get_timer_channels(unsigned timer) } else { if (channels_cache[timer] == 0) { - const io_timers_t *tmr = &io_timers[timer]; - /* Gather the channel bits that belong to the timer */ - for (unsigned chan_index = tmr->first_channel_index; chan_index <= tmr->last_channel_index; chan_index++) { + 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 (unsigned chan_index = first_channel_index; chan_index < last_channel_index; chan_index++) { channels |= 1 << chan_index; } @@ -527,7 +540,31 @@ int io_timer_set_dshot_mode(uint8_t timer, unsigned dshot_pwm_freq, uint8_t dma_ rARR(timer) = DSHOT_MOTOR_PWM_BIT_WIDTH; rPSC(timer) = ((int)(io_timers[timer].clock_freq / dshot_pwm_freq) / DSHOT_MOTOR_PWM_BIT_WIDTH) - 1; rEGR(timer) = ATIM_EGR_UG; - rDCR(timer) = (io_timers[timer].dshot.start_ccr_register | tim_dma_burst_length); + + // find the lowest channel index for the timer (they are not necesarily in ascending order) + unsigned lowest_timer_channel = 4; + 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 (unsigned chan_index = first_channel_index; chan_index < last_channel_index; chan_index++) { + if (timer_io_channels[chan_index].timer_channel < lowest_timer_channel) { + lowest_timer_channel = timer_io_channels[chan_index].timer_channel; + } + } + + uint32_t start_ccr_register = 0; + + switch (lowest_timer_channel) { + case 1: start_ccr_register = TIM_DMABASE_CCR1; break; + + case 2: start_ccr_register = TIM_DMABASE_CCR2; break; + + case 3: start_ccr_register = TIM_DMABASE_CCR3; break; + + case 4: start_ccr_register = TIM_DMABASE_CCR4; break; + } + + rDCR(timer) = start_ccr_register | tim_dma_burst_length; } return ret_val; @@ -621,10 +658,35 @@ int io_timer_init_timer(unsigned timer) * Note that the timer is left disabled with IRQ subs installed * and active but DEIR bits are not set. */ + xcpt_t handler; - irq_attach(io_timers[timer].vectorno, io_timers[timer].handler, NULL); + switch (timer) { + case 0: handler = io_timer_handler0; break; - up_enable_irq(io_timers[timer].vectorno); + case 1: handler = io_timer_handler1; break; + + case 2: handler = io_timer_handler2; break; + + case 3: handler = io_timer_handler3; break; + + case 4: handler = io_timer_handler4; break; + + case 5: handler = io_timer_handler5; break; + + case 6: handler = io_timer_handler6; break; + + case 7: handler = io_timer_handler7; break; + + default: + handler = NULL; + rv = -EINVAL; + break; + } + + if (handler) { + irq_attach(io_timers[timer].vectorno, handler, NULL); + up_enable_irq(io_timers[timer].vectorno); + } px4_leave_critical_section(flags); }