mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-31 02:16:53 +08:00
refactor(io_timer): make timer_io_channels[].timer_channel 0-indexed (#26845)
* refactor: make timer_io_channels[].timer_channel 0-indexed timer_channel was 1-indexed (1-4) to mirror STM32 hardware naming (TIM_CH1-CH4), but this was purely cosmetic — the ccr_offset field already handles register mapping. Every consumer did timer_channel - 1 to get a 0-based index, creating underflow bugs when the guard was missing (e.g. dshot.c capture_complete_callback, output_channel_from_timer_channel, up_bdshot_get_erpm). Changes: - STM32: Timer::Channel enum starts at 0, initIOTimerChannel assigns directly, removed all timer_channel - 1 in dshot.c and io_timer.c - NXP (kinetis, s32k1xx, s32k3xx): removed the + 1 in initIOTimerChannel, removed timer_channel - 1 in io_timer.c, led_pwm.cpp, and input_capture.c - RPI: Channel enum starts at 0, removed timer_channel - 1 in io_timer.c - Validity checks updated from timer_channel <= 0 || >= 5 to timer_channel >= 4 Closes #26747 Signed-off-by: Pavel Guzenfeld <pavelgu@gmail.com> * fix: complete 0-indexed timer_channel migration across all platforms Address review feedback for incomplete migration: 1. STM32H7 io_timer_hw_description.h: update standalone initIOTimerChannel() to assign timer_channel from enum (0-based) instead of hardcoded 1/2/3/4 2. Switch case labels: update all switch(timer_channel) blocks from 1/2/3/4 to 0/1/2/3 in: - stm32_common: input_capture.c (4 blocks), led_pwm.cpp (3), io_timer.c DMA base register switch - kinetis: input_capture.c (2 filter blocks) - s32k1xx: input_capture.c (2 filter blocks) - spix_sync.c (ark/fpv + ark/pi6x, 3 blocks each) 3. Sentinel checks: replace timer_channel != 0 / == 0 (which now conflicts with valid channel 0) with gpio_out-based checks in: - io_timer_validate_channel_index() across all 5 platforms - led_pwm_channel_init() and led_pwm_servo_get() in all led_pwm.cpp variants (STM32 + 4 NXP) - spix_sync_channel_init() and spix_sync_servo_get() Tested: px4_fmu-v6x_default (H7) build OK, px4_sitl_default build OK, 154/154 unit tests pass, ASan build clean. * fix: update NXP board led_pwm_channels to 0-indexed timer_channel These 4 board files manually specify led_pwm_channels[] with 1-indexed timer_channel values. Since the platform code no longer subtracts 1, decrement all values to match the new 0-indexed convention. * fix: correct FTM CH3 filter mask in kinetis and s32k1xx input capture Case 3 in up_input_capture_set_filter() was using CH2FVAL_MASK/SHIFT instead of CH3FVAL_MASK/SHIFT due to a copy-paste error, causing channel 3 filter writes to modify channel 2's filter register instead. --------- Signed-off-by: Pavel Guzenfeld <pavelgu@gmail.com> Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
This commit is contained in:
@@ -93,7 +93,7 @@ static void input_capture_chan_handler(void *context, const io_timers_t *timer,
|
||||
|
||||
channel_stats[chan_index].edges++;
|
||||
channel_stats[chan_index].last_time = isrs_time - (isrs_rcnt - capture);
|
||||
uint32_t overflow = 0;//_REG32(timer, KINETIS_FTM_CSC_OFFSET(chan->timer_channel - 1)) & FTM_CSC_CHF;
|
||||
uint32_t overflow = 0;//_REG32(timer, KINETIS_FTM_CSC_OFFSET(chan->timer_channel)) & FTM_CSC_CHF;
|
||||
|
||||
if (overflow) {
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
{
|
||||
/* Only initialize used channels */
|
||||
|
||||
if (led_pwm_channels[channel].timer_channel) {
|
||||
if (led_pwm_channels[channel].gpio_out) {
|
||||
unsigned timer = led_pwm_channels[channel].timer_index;
|
||||
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
@@ -249,7 +249,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel - 1;
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel;
|
||||
|
||||
uint16_t rvalue = REG(timer, KINETIS_FTM_CSC_OFFSET(chan));
|
||||
rvalue &= ~CnSC_RESET;
|
||||
@@ -284,7 +284,7 @@ led_pwm_servo_set(unsigned channel, uint8_t cvalue)
|
||||
value--;
|
||||
}
|
||||
|
||||
REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel - 1)) = value;
|
||||
REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel)) = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -300,11 +300,11 @@ unsigned led_pwm_servo_get(unsigned channel)
|
||||
|
||||
/* test timer for validity */
|
||||
if ((led_pwm_timers[timer].base == 0) ||
|
||||
(led_pwm_channels[channel].timer_channel == 0)) {
|
||||
(led_pwm_channels[channel].gpio_out == 0)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value = REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel - 1));
|
||||
value = REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel));
|
||||
unsigned period = led_pwm_timer_get_period(timer);
|
||||
return ((value + 1) * 255 / period);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
|
||||
ret.gpio_in = gpio_af | gpio_pin_port;
|
||||
ret.gpio_out = gpio_af | gpio_pin_port;
|
||||
|
||||
ret.timer_channel = (int)timer.channel + 1;
|
||||
ret.timer_channel = (uint8_t)timer.channel;
|
||||
|
||||
// find timer index
|
||||
ret.timer_index = 0xff;
|
||||
|
||||
@@ -110,7 +110,7 @@ static void input_capture_chan_handler(void *context, const io_timers_t *timer,
|
||||
|
||||
channel_stats[chan_index].edges++;
|
||||
channel_stats[chan_index].last_time = isrs_time - (isrs_rcnt - capture);
|
||||
uint32_t overflow = _REG32(timer, KINETIS_FTM_CSC_OFFSET(chan->timer_channel - 1)) & FTM_CSC_CHF;
|
||||
uint32_t overflow = _REG32(timer, KINETIS_FTM_CSC_OFFSET(chan->timer_channel)) & FTM_CSC_CHF;
|
||||
|
||||
if (overflow) {
|
||||
|
||||
@@ -157,7 +157,7 @@ int up_input_capture_set(unsigned channel, input_capture_edge edge, capture_filt
|
||||
/* This register selects the filter value for the inputs of channels.
|
||||
Channels 4, 5, 6 and 7 do not have an input filter.
|
||||
*/
|
||||
if (filter && timer_io_channels[channel].timer_channel - 1 > 3) {
|
||||
if (filter && timer_io_channels[channel].timer_channel > 3) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ int up_input_capture_get_filter(unsigned channel, capture_filter_t *filter)
|
||||
|
||||
rv = -EINVAL;
|
||||
|
||||
if (timer_io_channels[channel].timer_channel - 1 <= 3) {
|
||||
if (timer_io_channels[channel].timer_channel <= 3) {
|
||||
rv = -ENXIO;
|
||||
|
||||
/* Any pins in capture mode */
|
||||
@@ -213,22 +213,22 @@ int up_input_capture_get_filter(unsigned channel, capture_filter_t *filter)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH0FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH0FVAL_SHIFT);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH1FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH1FVAL_SHIFT);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH2FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH2FVAL_SHIFT);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH3FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH3FVAL_SHIFT);
|
||||
break;
|
||||
@@ -266,27 +266,27 @@ int up_input_capture_set_filter(unsigned channel, capture_filter_t filter)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH0FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH0FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH1FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH1FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH2FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH2FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH2FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH2FVAL_SHIFT);
|
||||
case 3:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH3FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH3FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
@@ -316,7 +316,7 @@ int up_input_capture_get_trigger(unsigned channel, input_capture_edge *edge)
|
||||
rv = OK;
|
||||
|
||||
uint32_t timer = timer_io_channels[channel].timer_index;
|
||||
uint16_t rvalue = _REG32(timer, KINETIS_FTM_CSC_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
uint16_t rvalue = _REG32(timer, KINETIS_FTM_CSC_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
rvalue &= (FTM_CSC_MSB | FTM_CSC_MSA);
|
||||
|
||||
switch (rvalue) {
|
||||
@@ -377,10 +377,10 @@ int up_input_capture_set_trigger(unsigned channel, input_capture_edge edge)
|
||||
|
||||
uint32_t timer = timer_io_channels[channel].timer_index;
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
uint32_t rvalue = _REG32(timer, KINETIS_FTM_CSC_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
uint32_t rvalue = _REG32(timer, KINETIS_FTM_CSC_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
rvalue &= (FTM_CSC_MSB | FTM_CSC_MSA);
|
||||
rvalue |= edge_bits;
|
||||
_REG32(timer, KINETIS_FTM_CSC_OFFSET(timer_io_channels[channel].timer_channel - 1)) = rvalue;
|
||||
_REG32(timer, KINETIS_FTM_CSC_OFFSET(timer_io_channels[channel].timer_channel)) = rvalue;
|
||||
px4_leave_critical_section(flags);
|
||||
rv = OK;
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ int io_timer_validate_channel_index(unsigned channel)
|
||||
{
|
||||
int rv = -EINVAL;
|
||||
|
||||
if (channel < MAX_TIMER_IO_CHANNELS && timer_io_channels[channel].timer_channel != 0) {
|
||||
if (channel < MAX_TIMER_IO_CHANNELS) {
|
||||
|
||||
unsigned timer = timer_io_channels[channel].timer_index;
|
||||
|
||||
@@ -740,7 +740,7 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t chan = timer_io_channels[channel].timer_channel - 1;
|
||||
uint32_t chan = timer_io_channels[channel].timer_channel;
|
||||
|
||||
uint16_t rvalue = REG(timer, KINETIS_FTM_CSC_OFFSET(chan));
|
||||
rvalue &= ~clearbits;
|
||||
@@ -820,7 +820,7 @@ int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, io_timer_chann
|
||||
masks &= ~(1 << chan_index);
|
||||
|
||||
if (io_timer_validate_channel_index(chan_index) == 0) {
|
||||
uint32_t chan = timer_io_channels[chan_index].timer_channel - 1;
|
||||
uint32_t chan = timer_io_channels[chan_index].timer_channel;
|
||||
uint32_t timer = channels_timer(chan_index);
|
||||
action_cache[timer].base = io_timers[timer].base;
|
||||
action_cache[timer].cnsc[action_cache[timer].index].cnsc_offset = io_timers[timer].base + KINETIS_FTM_CSC_OFFSET(chan);
|
||||
@@ -905,7 +905,7 @@ int io_timer_set_ccr(unsigned channel, uint16_t value)
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
uint32_t save = rSC(timer);
|
||||
rSC(timer) = save & ~(FTM_SC_CLKS_MASK);
|
||||
REG(timer, KINETIS_FTM_CV_OFFSET(timer_io_channels[channel].timer_channel - 1)) = value;
|
||||
REG(timer, KINETIS_FTM_CV_OFFSET(timer_io_channels[channel].timer_channel)) = value;
|
||||
rSC(timer) = save;
|
||||
px4_leave_critical_section(flags);
|
||||
}
|
||||
@@ -924,7 +924,7 @@ uint16_t io_channel_get_ccr(unsigned channel)
|
||||
if ((mode == IOTimerChanMode_PWMOut) ||
|
||||
(mode == IOTimerChanMode_OneShot) ||
|
||||
(mode == IOTimerChanMode_Trigger)) {
|
||||
value = REG(channels_timer(channel), KINETIS_FTM_CV_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
value = REG(channels_timer(channel), KINETIS_FTM_CV_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
{
|
||||
/* Only initialize used channels */
|
||||
|
||||
if (led_pwm_channels[channel].timer_channel) {
|
||||
if (led_pwm_channels[channel].gpio_out) {
|
||||
unsigned timer = led_pwm_channels[channel].timer_index;
|
||||
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
@@ -239,7 +239,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel - 1;
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel;
|
||||
|
||||
uint16_t rvalue = REG(timer, KINETIS_FTM_CSC_OFFSET(chan));
|
||||
rvalue &= ~CnSC_RESET;
|
||||
@@ -274,7 +274,7 @@ led_pwm_servo_set(unsigned channel, uint8_t cvalue)
|
||||
value--;
|
||||
}
|
||||
|
||||
REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel - 1)) = value;
|
||||
REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel)) = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -290,11 +290,11 @@ unsigned led_pwm_servo_get(unsigned channel)
|
||||
|
||||
/* test timer for validity */
|
||||
if ((led_pwm_timers[timer].base == 0) ||
|
||||
(led_pwm_channels[channel].timer_channel == 0)) {
|
||||
(led_pwm_channels[channel].gpio_out == 0)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value = REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel - 1));
|
||||
value = REG(timer, KINETIS_FTM_CV_OFFSET(led_pwm_channels[channel].timer_channel));
|
||||
unsigned period = led_pwm_timer_get_period(timer);
|
||||
return ((value + 1) * 255 / period);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
|
||||
ret.gpio_in = gpio_af | gpio_pin_port;
|
||||
ret.gpio_out = gpio_af | gpio_pin_port;
|
||||
|
||||
ret.timer_channel = (int)timer.channel + 1;
|
||||
ret.timer_channel = (uint8_t)timer.channel;
|
||||
|
||||
// find timer index
|
||||
ret.timer_index = 0xff;
|
||||
|
||||
@@ -110,7 +110,7 @@ static void input_capture_chan_handler(void *context, const io_timers_t *timer,
|
||||
|
||||
channel_stats[chan_index].edges++;
|
||||
channel_stats[chan_index].last_time = isrs_time - (isrs_rcnt - capture);
|
||||
uint32_t overflow = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(chan->timer_channel - 1)) & FTM_CNSC_CHF;
|
||||
uint32_t overflow = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(chan->timer_channel)) & FTM_CNSC_CHF;
|
||||
|
||||
if (overflow) {
|
||||
|
||||
@@ -157,7 +157,7 @@ int up_input_capture_set(unsigned channel, input_capture_edge edge, capture_filt
|
||||
/* This register selects the filter value for the inputs of channels.
|
||||
Channels 4, 5, 6 and 7 do not have an input filter.
|
||||
*/
|
||||
if (filter && timer_io_channels[channel].timer_channel - 1 > 3) {
|
||||
if (filter && timer_io_channels[channel].timer_channel > 3) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ int up_input_capture_get_filter(unsigned channel, capture_filter_t *filter)
|
||||
|
||||
rv = -EINVAL;
|
||||
|
||||
if (timer_io_channels[channel].timer_channel - 1 <= 3) {
|
||||
if (timer_io_channels[channel].timer_channel <= 3) {
|
||||
rv = -ENXIO;
|
||||
|
||||
/* Any pins in capture mode */
|
||||
@@ -213,22 +213,22 @@ int up_input_capture_get_filter(unsigned channel, capture_filter_t *filter)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH0FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH0FVAL_SHIFT);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH1FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH1FVAL_SHIFT);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH2FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH2FVAL_SHIFT);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rvalue = rFILTER(timer) & FTM_FILTER_CH3FVAL_MASK;
|
||||
*filter = (rvalue >> FTM_FILTER_CH3FVAL_SHIFT);
|
||||
break;
|
||||
@@ -266,27 +266,27 @@ int up_input_capture_set_filter(unsigned channel, capture_filter_t filter)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH0FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH0FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH1FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH1FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH2FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH2FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH2FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH2FVAL_SHIFT);
|
||||
case 3:
|
||||
rvalue = rFILTER(timer) & ~FTM_FILTER_CH3FVAL_MASK;
|
||||
rvalue |= (filter << FTM_FILTER_CH3FVAL_SHIFT);
|
||||
rFILTER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
@@ -316,7 +316,7 @@ int up_input_capture_get_trigger(unsigned channel, input_capture_edge *edge)
|
||||
rv = OK;
|
||||
|
||||
uint32_t timer = timer_io_channels[channel].timer_index;
|
||||
uint16_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
uint16_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
rvalue &= (FTM_CNSC_MSB | FTM_CNSC_MSA);
|
||||
|
||||
switch (rvalue) {
|
||||
@@ -377,10 +377,10 @@ int up_input_capture_set_trigger(unsigned channel, input_capture_edge edge)
|
||||
|
||||
uint32_t timer = timer_io_channels[channel].timer_index;
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
uint32_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
uint32_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
rvalue &= (FTM_CNSC_MSB | FTM_CNSC_MSA);
|
||||
rvalue |= edge_bits;
|
||||
_REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel - 1)) = rvalue;
|
||||
_REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel)) = rvalue;
|
||||
px4_leave_critical_section(flags);
|
||||
rv = OK;
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ int io_timer_validate_channel_index(unsigned channel)
|
||||
{
|
||||
int rv = -EINVAL;
|
||||
|
||||
if (channel < MAX_TIMER_IO_CHANNELS && timer_io_channels[channel].timer_channel != 0) {
|
||||
if (channel < MAX_TIMER_IO_CHANNELS) {
|
||||
|
||||
unsigned timer = timer_io_channels[channel].timer_index;
|
||||
|
||||
@@ -742,7 +742,7 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t chan = timer_io_channels[channel].timer_channel - 1;
|
||||
uint32_t chan = timer_io_channels[channel].timer_channel;
|
||||
|
||||
uint16_t rvalue = REG(timer, S32K1XX_FTM_CNSC_OFFSET(chan));
|
||||
rvalue &= ~clearbits;
|
||||
@@ -823,7 +823,7 @@ int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, io_timer_chann
|
||||
masks &= ~(1 << chan_index);
|
||||
|
||||
if (io_timer_validate_channel_index(chan_index) == 0) {
|
||||
uint32_t chan = timer_io_channels[chan_index].timer_channel - 1;
|
||||
uint32_t chan = timer_io_channels[chan_index].timer_channel;
|
||||
uint32_t timer = channels_timer(chan_index);
|
||||
action_cache[timer].base = io_timers[timer].base;
|
||||
action_cache[timer].cnsc[action_cache[timer].index].cnsc_offset = io_timers[timer].base + S32K1XX_FTM_CNSC_OFFSET(chan);
|
||||
@@ -912,7 +912,7 @@ int io_timer_set_ccr(unsigned channel, uint16_t value)
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
uint32_t save = rSC(timer);
|
||||
rSC(timer) = save & ~(FTM_SC_CLKS_MASK);
|
||||
REG(timer, S32K1XX_FTM_CNV_OFFSET(timer_io_channels[channel].timer_channel - 1)) = value;
|
||||
REG(timer, S32K1XX_FTM_CNV_OFFSET(timer_io_channels[channel].timer_channel)) = value;
|
||||
rSC(timer) = save;
|
||||
px4_leave_critical_section(flags);
|
||||
}
|
||||
@@ -931,7 +931,7 @@ uint16_t io_channel_get_ccr(unsigned channel)
|
||||
if ((mode == IOTimerChanMode_PWMOut) ||
|
||||
(mode == IOTimerChanMode_OneShot) ||
|
||||
(mode == IOTimerChanMode_Trigger)) {
|
||||
value = REG(channels_timer(channel), S32K1XX_FTM_CNV_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
value = REG(channels_timer(channel), S32K1XX_FTM_CNV_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
{
|
||||
/* Only initialize used channels */
|
||||
|
||||
if (led_pwm_channels[channel].timer_channel) {
|
||||
if (led_pwm_channels[channel].gpio_out) {
|
||||
unsigned timer = led_pwm_channels[channel].timer_index;
|
||||
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
@@ -239,7 +239,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel - 1;
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel;
|
||||
|
||||
uint16_t rvalue = REG(timer, S32K1XX_FTM_CNSC_OFFSET(chan));
|
||||
rvalue &= ~CnSC_RESET;
|
||||
@@ -275,7 +275,7 @@ led_pwm_servo_set(unsigned channel, uint8_t cvalue)
|
||||
value--;
|
||||
}
|
||||
|
||||
REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel - 1)) = value;
|
||||
REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel)) = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -291,11 +291,11 @@ unsigned led_pwm_servo_get(unsigned channel)
|
||||
|
||||
/* test timer for validity */
|
||||
if ((led_pwm_timers[timer].base == 0) ||
|
||||
(led_pwm_channels[channel].timer_channel == 0)) {
|
||||
(led_pwm_channels[channel].gpio_out == 0)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value = REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel - 1));
|
||||
value = REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel));
|
||||
unsigned period = led_pwm_timer_get_period(timer);
|
||||
return ((value + 1) * 255 / period);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
|
||||
ret.gpio_in = pinmux;
|
||||
ret.gpio_out = pinmux;
|
||||
|
||||
ret.timer_channel = (int)timer.channel + 1;
|
||||
ret.timer_channel = (uint8_t)timer.channel;
|
||||
|
||||
// find timer index
|
||||
ret.timer_index = timer.channel;
|
||||
|
||||
@@ -108,7 +108,7 @@ static void input_capture_chan_handler(void *context, const io_timers_t *timer,
|
||||
|
||||
channel_stats[chan_index].edges++;
|
||||
channel_stats[chan_index].last_time = isrs_time - (isrs_rcnt - capture);
|
||||
uint32_t overflow = 0;//_REG32(timer, S32K1XX_FTM_CNSC_OFFSET(chan->timer_channel - 1)) & FTM_CNSC_CHF;
|
||||
uint32_t overflow = 0;//_REG32(timer, S32K1XX_FTM_CNSC_OFFSET(chan->timer_channel)) & FTM_CNSC_CHF;
|
||||
|
||||
if (overflow) {
|
||||
|
||||
@@ -155,7 +155,7 @@ int up_input_capture_set(unsigned channel, input_capture_edge edge, capture_filt
|
||||
/* This register selects the filter value for the inputs of channels.
|
||||
Channels 4, 5, 6 and 7 do not have an input filter.
|
||||
*/
|
||||
if (filter && timer_io_channels[channel].timer_channel - 1 > 3) {
|
||||
if (filter && timer_io_channels[channel].timer_channel > 3) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ int up_input_capture_get_filter(unsigned channel, capture_filter_t *filter)
|
||||
|
||||
rv = -EINVAL;
|
||||
|
||||
if (timer_io_channels[channel].timer_channel - 1 <= 3) {
|
||||
if (timer_io_channels[channel].timer_channel <= 3) {
|
||||
rv = -ENXIO;
|
||||
|
||||
/* Any pins in capture mode */
|
||||
@@ -274,7 +274,7 @@ int up_input_capture_get_trigger(unsigned channel, input_capture_edge *edge)
|
||||
rv = OK;
|
||||
|
||||
//uint32_t timer = timer_io_channels[channel].timer_index;
|
||||
/*uint16_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
/*uint16_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
rvalue &= (FTM_CNSC_MSB | FTM_CNSC_MSA);
|
||||
|
||||
switch (rvalue) {
|
||||
@@ -335,10 +335,10 @@ int up_input_capture_set_trigger(unsigned channel, input_capture_edge edge)
|
||||
|
||||
//uint32_t timer = timer_io_channels[channel].timer_index;
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
/*uint32_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel - 1));
|
||||
/*uint32_t rvalue = _REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel));
|
||||
rvalue &= (FTM_CNSC_MSB | FTM_CNSC_MSA);
|
||||
rvalue |= edge_bits;
|
||||
_REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel - 1)) = rvalue;*/
|
||||
_REG32(timer, S32K1XX_FTM_CNSC_OFFSET(timer_io_channels[channel].timer_channel)) = rvalue;*/
|
||||
px4_leave_critical_section(flags);
|
||||
rv = OK;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ int io_timer_validate_channel_index(unsigned channel)
|
||||
{
|
||||
int rv = -EINVAL;
|
||||
|
||||
if (channel < MAX_TIMER_IO_CHANNELS && timer_io_channels[channel].timer_channel != 0) {
|
||||
if (channel < MAX_TIMER_IO_CHANNELS) {
|
||||
|
||||
unsigned timer = timer_io_channels[channel].timer_index;
|
||||
|
||||
@@ -731,7 +731,7 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t chan = timer_io_channels[channel].timer_channel - 1;
|
||||
uint32_t chan = timer_io_channels[channel].timer_channel;
|
||||
|
||||
//FIXME use setbits/clearbits for different modes
|
||||
|
||||
@@ -830,7 +830,7 @@ int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, io_timer_chann
|
||||
masks &= ~(1 << chan_index);
|
||||
|
||||
if (io_timer_validate_channel_index(chan_index) == 0) {
|
||||
uint32_t chan = timer_io_channels[chan_index].timer_channel - 1;
|
||||
uint32_t chan = timer_io_channels[chan_index].timer_channel;
|
||||
uint32_t timer = channels_timer(chan_index);
|
||||
|
||||
if ((state &&
|
||||
@@ -875,7 +875,7 @@ int io_timer_set_ccr(unsigned channel, uint16_t value)
|
||||
|
||||
/* configure the channel */
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
rA(channels_timer(channel), timer_io_channels[channel].timer_channel - 1) = EMIOS_A(value * 2);
|
||||
rA(channels_timer(channel), timer_io_channels[channel].timer_channel) = EMIOS_A(value * 2);
|
||||
px4_leave_critical_section(flags);
|
||||
}
|
||||
}
|
||||
@@ -895,7 +895,7 @@ uint16_t io_channel_get_ccr(unsigned channel)
|
||||
(mode == IOTimerChanMode_OneShot) ||
|
||||
(mode == IOTimerChanMode_Trigger)) {
|
||||
/* Read rALTA to fetch AS2 shadow register */
|
||||
value = (rALTA(channels_timer(channel), timer_io_channels[channel].timer_channel - 1) & EMIOS_A_MASK) / 2;
|
||||
value = (rALTA(channels_timer(channel), timer_io_channels[channel].timer_channel) & EMIOS_A_MASK) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
{
|
||||
/* Only initialize used channels */
|
||||
|
||||
if (led_pwm_channels[channel].timer_channel) {
|
||||
if (led_pwm_channels[channel].gpio_out) {
|
||||
unsigned timer = led_pwm_channels[channel].timer_index;
|
||||
|
||||
irqstate_t flags = px4_enter_critical_section();
|
||||
@@ -239,7 +239,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel - 1;
|
||||
uint32_t chan = led_pwm_channels[channel].timer_channel;
|
||||
|
||||
uint16_t rvalue = REG(timer, S32K1XX_FTM_CNSC_OFFSET(chan));
|
||||
rvalue &= ~CnSC_RESET;
|
||||
@@ -275,7 +275,7 @@ led_pwm_servo_set(unsigned channel, uint8_t cvalue)
|
||||
value--;
|
||||
}
|
||||
|
||||
REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel - 1)) = value;
|
||||
REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel)) = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -291,11 +291,11 @@ led_pwm_servo_get(unsigned channel)
|
||||
|
||||
/* test timer for validity */
|
||||
if ((led_pwm_timers[timer].base == 0) ||
|
||||
(led_pwm_channels[channel].timer_channel == 0)) {
|
||||
(led_pwm_channels[channel].gpio_out == 0)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value = REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel - 1));
|
||||
value = REG(timer, S32K1XX_FTM_CNV_OFFSET(led_pwm_channels[channel].timer_channel));
|
||||
unsigned period = led_pwm_timer_get_period(timer);
|
||||
return ((value + 1) * 255 / period);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ enum Timer {
|
||||
Timer7,
|
||||
};
|
||||
enum Channel {
|
||||
ChannelA = 1,
|
||||
ChannelA = 0,
|
||||
ChannelB,
|
||||
};
|
||||
struct TimerChannel {
|
||||
|
||||
@@ -266,7 +266,7 @@ int io_timer_validate_channel_index(unsigned channel)
|
||||
{
|
||||
int rv = -EINVAL;
|
||||
|
||||
if (channel < MAX_TIMER_IO_CHANNELS && timer_io_channels[channel].timer_channel != 0) {
|
||||
if (channel < MAX_TIMER_IO_CHANNELS) {
|
||||
|
||||
unsigned timer = timer_io_channels[channel].timer_index;
|
||||
|
||||
@@ -602,7 +602,7 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
|
||||
|
||||
/* configure the channel */ // Nothing to configure here really.
|
||||
|
||||
// uint32_t chan = timer_io_channels[channel].timer_channel - 1;
|
||||
// uint32_t chan = timer_io_channels[channel].timer_channel;
|
||||
|
||||
channel_handlers[channel].callback = channel_handler;
|
||||
channel_handlers[channel].context = context;
|
||||
@@ -664,7 +664,7 @@ int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, io_timer_chann
|
||||
masks &= ~(1 << chan_index);
|
||||
|
||||
if (io_timer_validate_channel_index(chan_index) == 0) {
|
||||
// uint32_t chan = timer_io_channels[chan_index].timer_channel - 1;
|
||||
// uint32_t chan = timer_io_channels[chan_index].timer_channel;
|
||||
uint32_t timer = channels_timer(chan_index);
|
||||
action_cache[timer].base = io_timers[timer].base;
|
||||
// action_cache[timer].cnsc[action_cache[timer].index].cnsc_offset = io_timers[timer].base + KINETIS_FTM_CSC_OFFSET(chan);
|
||||
@@ -739,8 +739,8 @@ int io_timer_set_ccr(unsigned channel, uint16_t value)
|
||||
|
||||
/* configure the channel */
|
||||
int regVal = rCCR(channels_timer(channel));
|
||||
regVal &= ~(0xffff << (timer_io_channels[channel].timer_channel - 1) * 16);
|
||||
regVal |= value << (timer_io_channels[channel].timer_channel - 1) * 16;
|
||||
regVal &= ~(0xffff << (timer_io_channels[channel].timer_channel) * 16);
|
||||
regVal |= value << (timer_io_channels[channel].timer_channel) * 16;
|
||||
rCCR(channels_timer(channel)) = regVal;
|
||||
}
|
||||
}
|
||||
@@ -758,7 +758,7 @@ uint16_t io_channel_get_ccr(unsigned channel)
|
||||
if ((mode == IOTimerChanMode_PWMOut) ||
|
||||
(mode == IOTimerChanMode_OneShot) ||
|
||||
(mode == IOTimerChanMode_Trigger)) {
|
||||
value = rCCR(channels_timer(channel)) >> (timer_io_channels[channel].timer_channel - 1) * 16;
|
||||
value = rCCR(channels_timer(channel)) >> (timer_io_channels[channel].timer_channel) * 16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -191,13 +191,11 @@ static void init_timer_config(uint32_t channel_mask)
|
||||
|
||||
uint8_t timer_channel = timer_io_channels[output_channel].timer_channel;
|
||||
|
||||
if ((timer_channel <= 0) || (timer_channel >= 5)) {
|
||||
// invalid channel, only 1 - 4
|
||||
if (timer_channel >= 4) {
|
||||
// invalid channel, only 0 - 3
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t timer_channel_index = timer_channel - 1;
|
||||
|
||||
if (io_timers[timer_index].dshot.dma_base == 0) {
|
||||
// board does not configure dshot on this timer
|
||||
continue;
|
||||
@@ -205,7 +203,7 @@ static void init_timer_config(uint32_t channel_mask)
|
||||
|
||||
timer_configs[timer_index].timer_index = timer_index;
|
||||
timer_configs[timer_index].enabled = true;
|
||||
timer_configs[timer_index].enabled_channels[timer_channel_index] = true;
|
||||
timer_configs[timer_index].enabled_channels[timer_channel] = true;
|
||||
|
||||
// TODO: bdshot per timer not on all timers
|
||||
// Mark timer as bidirectional
|
||||
@@ -275,14 +273,13 @@ static int32_t init_timer_channels(uint8_t timer_index)
|
||||
|
||||
uint8_t timer_channel = timer_io_channels[output_channel].timer_channel;
|
||||
|
||||
if ((timer_channel <= 0) || (timer_channel >= 5)) {
|
||||
// invalid channel, only 1 - 4
|
||||
if (timer_channel >= 4) {
|
||||
// invalid channel, only 0 - 3
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t timer_channel_index = timer_channel - 1;
|
||||
bool this_timer = timer_index == timer_io_channels[output_channel].timer_index;
|
||||
bool channel_enabled = timer_configs[timer_index].enabled_channels[timer_channel_index];
|
||||
bool channel_enabled = timer_configs[timer_index].enabled_channels[timer_channel];
|
||||
|
||||
if (this_timer && channel_enabled) {
|
||||
int ret = io_timer_channel_init(output_channel, mode, NULL, NULL);
|
||||
@@ -292,7 +289,7 @@ static int32_t init_timer_channels(uint8_t timer_index)
|
||||
continue;
|
||||
}
|
||||
|
||||
timer_configs[timer_index].initialized_channels[timer_channel_index] = true;
|
||||
timer_configs[timer_index].initialized_channels[timer_channel] = true;
|
||||
channels_init_mask |= (1 << output_channel);
|
||||
|
||||
PX4_DEBUG("%sDShot initialized OutputChannel %u", timer_configs[timer_index].bidirectional ? "B" : "", output_channel);
|
||||
@@ -366,10 +363,8 @@ int up_dshot_init(uint32_t channel_mask, uint32_t bdshot_channel_mask, unsigned
|
||||
uint8_t timer_index = timer_io_channels[output_channel].timer_index;
|
||||
uint8_t timer_channel = timer_io_channels[output_channel].timer_channel;
|
||||
|
||||
if (timer_channel >= 1 && timer_channel <= 4) {
|
||||
uint8_t timer_channel_index = timer_channel - 1;
|
||||
|
||||
if (io_timers[timer_index].dshot.dma_map_ch[timer_channel_index] != 0) {
|
||||
if (timer_channel < 4) {
|
||||
if (io_timers[timer_index].dshot.dma_map_ch[timer_channel] != 0) {
|
||||
_bdshot_capture_supported[output_channel] = true;
|
||||
|
||||
} else {
|
||||
@@ -509,7 +504,7 @@ static uint8_t output_channel_from_timer_channel(uint8_t timer_index, uint8_t ti
|
||||
for (uint8_t output_channel = 0; output_channel < MAX_TIMER_IO_CHANNELS; output_channel++) {
|
||||
|
||||
bool is_this_timer = timer_index == timer_io_channels[output_channel].timer_index;
|
||||
uint8_t channel_index = timer_io_channels[output_channel].timer_channel - 1;
|
||||
uint8_t channel_index = timer_io_channels[output_channel].timer_channel;
|
||||
|
||||
if (is_this_timer && (channel_index == timer_channel_index)) {
|
||||
// We found the output channel associated with this timer channel
|
||||
@@ -632,7 +627,7 @@ static void capture_complete_callback(void *arg)
|
||||
for (uint8_t output_channel = 0; output_channel < MAX_TIMER_IO_CHANNELS; output_channel++) {
|
||||
|
||||
bool is_this_timer = timer_index == timer_io_channels[output_channel].timer_index;
|
||||
uint8_t timer_channel_index = timer_io_channels[output_channel].timer_channel - 1;
|
||||
uint8_t timer_channel_index = timer_io_channels[output_channel].timer_channel;
|
||||
bool channel_initialized = timer_configs[timer_index].initialized_channels[timer_channel_index];
|
||||
|
||||
if (is_this_timer && channel_initialized) {
|
||||
@@ -923,7 +918,7 @@ void dshot_motor_data_set(uint8_t channel, uint16_t data, bool telemetry)
|
||||
}
|
||||
|
||||
uint8_t timer_index = timer_io_channels[channel].timer_index;
|
||||
uint8_t timer_channel_index = timer_io_channels[channel].timer_channel - 1;
|
||||
uint8_t timer_channel_index = timer_io_channels[channel].timer_channel;
|
||||
bool channel_initialized = timer_configs[timer_index].initialized_channels[timer_channel_index];
|
||||
|
||||
if (!channel_initialized) {
|
||||
@@ -999,7 +994,7 @@ int up_bdshot_get_erpm(uint8_t channel, int *erpm)
|
||||
}
|
||||
|
||||
uint8_t timer_index = timer_io_channels[channel].timer_index;
|
||||
uint8_t timer_channel_index = timer_io_channels[channel].timer_channel - 1;
|
||||
uint8_t timer_channel_index = timer_io_channels[channel].timer_channel;
|
||||
bool channel_initialized = timer_configs[timer_index].initialized_channels[timer_channel_index];
|
||||
|
||||
if (channel_initialized && _erpms[channel].ready) {
|
||||
|
||||
@@ -102,7 +102,7 @@ enum Timer {
|
||||
#endif
|
||||
};
|
||||
enum Channel {
|
||||
Channel1 = 1,
|
||||
Channel1 = 0,
|
||||
Channel2,
|
||||
Channel3,
|
||||
Channel4,
|
||||
|
||||
@@ -52,29 +52,27 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
|
||||
|
||||
// TODO: here we could validate that pin actually maps to the given timer channel
|
||||
|
||||
ret.timer_channel = (uint8_t)timer.channel;
|
||||
|
||||
switch (timer.channel) {
|
||||
case Timer::Channel1:
|
||||
ret.ccr_offset = STM32_GTIM_CCR1_OFFSET;
|
||||
ret.masks = GTIM_SR_CC1IF | GTIM_SR_CC1OF;
|
||||
ret.timer_channel = 1;
|
||||
break;
|
||||
|
||||
case Timer::Channel2:
|
||||
ret.ccr_offset = STM32_GTIM_CCR2_OFFSET;
|
||||
ret.masks = GTIM_SR_CC2IF | GTIM_SR_CC2OF;
|
||||
ret.timer_channel = 2;
|
||||
break;
|
||||
|
||||
case Timer::Channel3:
|
||||
ret.ccr_offset = STM32_GTIM_CCR3_OFFSET;
|
||||
ret.masks = GTIM_SR_CC3IF | GTIM_SR_CC3OF;
|
||||
ret.timer_channel = 3;
|
||||
break;
|
||||
|
||||
case Timer::Channel4:
|
||||
ret.ccr_offset = STM32_GTIM_CCR4_OFFSET;
|
||||
ret.masks = GTIM_SR_CC4IF | GTIM_SR_CC4OF;
|
||||
ret.timer_channel = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -203,22 +203,22 @@ int up_input_capture_get_filter(unsigned channel, capture_filter_t *filter)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rCCMR1(timer) & GTIM_CCMR1_IC1F_MASK;
|
||||
*filter = (rvalue >> GTIM_CCMR1_IC1F_SHIFT);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rCCMR1(timer) & GTIM_CCMR1_IC2F_MASK;
|
||||
*filter = (rvalue >> GTIM_CCMR1_IC2F_SHIFT);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rCCMR2(timer) & GTIM_CCMR2_IC3F_MASK;
|
||||
*filter = (rvalue >> GTIM_CCMR2_IC3F_SHIFT);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rvalue = rCCMR2(timer) & GTIM_CCMR2_IC4F_MASK;
|
||||
*filter = (rvalue >> GTIM_CCMR2_IC4F_SHIFT);
|
||||
break;
|
||||
@@ -255,25 +255,25 @@ int up_input_capture_set_filter(unsigned channel, capture_filter_t filter)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rCCMR1(timer) & ~GTIM_CCMR1_IC1F_MASK;
|
||||
rvalue |= (filter << GTIM_CCMR1_IC1F_SHIFT);
|
||||
rCCMR1(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rCCMR1(timer) & ~GTIM_CCMR1_IC2F_MASK;
|
||||
rvalue |= (filter << GTIM_CCMR1_IC2F_SHIFT);
|
||||
rCCMR1(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rCCMR2(timer) & ~GTIM_CCMR2_IC3F_MASK;
|
||||
rvalue |= (filter << GTIM_CCMR2_IC3F_SHIFT);
|
||||
rCCMR2(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rvalue = rCCMR2(timer) & ~GTIM_CCMR2_IC4F_MASK;
|
||||
rvalue |= (filter << GTIM_CCMR2_IC4F_SHIFT);
|
||||
rCCMR2(timer) = rvalue;
|
||||
@@ -309,21 +309,21 @@ int up_input_capture_get_trigger(unsigned channel, input_capture_edge *edge)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rCCER(timer) & (GTIM_CCER_CC1P | GTIM_CCER_CC1NP);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rCCER(timer) & (GTIM_CCER_CC2P | GTIM_CCER_CC2NP);
|
||||
rvalue >>= 4;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rCCER(timer) & (GTIM_CCER_CC3P | GTIM_CCER_CC3NP);
|
||||
rvalue >>= 8;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rvalue = rCCER(timer) & (GTIM_CCER_CC4P | GTIM_CCER_CC4NP);
|
||||
rvalue >>= 12;
|
||||
break;
|
||||
@@ -400,28 +400,28 @@ int up_input_capture_set_trigger(unsigned channel, input_capture_edge edge)
|
||||
|
||||
switch (timer_io_channels[channel].timer_channel) {
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
rvalue = rCCER(timer);
|
||||
rvalue &= ~(GTIM_CCER_CC1P | GTIM_CCER_CC1NP);
|
||||
rvalue |= edge_bits;
|
||||
rCCER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rvalue = rCCER(timer);
|
||||
rvalue &= ~(GTIM_CCER_CC2P | GTIM_CCER_CC2NP);
|
||||
rvalue |= (edge_bits << 4);
|
||||
rCCER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rvalue = rCCER(timer);
|
||||
rvalue &= ~(GTIM_CCER_CC3P | GTIM_CCER_CC3NP);
|
||||
rvalue |= edge_bits << 8;
|
||||
rCCER(timer) = rvalue;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rvalue = rCCER(timer);
|
||||
rvalue &= ~(GTIM_CCER_CC4P | GTIM_CCER_CC4NP);
|
||||
rvalue |= edge_bits << 12;
|
||||
|
||||
@@ -357,7 +357,7 @@ int io_timer_validate_channel_index(unsigned channel)
|
||||
{
|
||||
int rv = -EINVAL;
|
||||
|
||||
if (channel < MAX_TIMER_IO_CHANNELS && timer_io_channels[channel].timer_channel != 0) {
|
||||
if (channel < MAX_TIMER_IO_CHANNELS) {
|
||||
|
||||
unsigned timer = timer_io_channels[channel].timer_index;
|
||||
|
||||
@@ -606,7 +606,7 @@ int io_timer_set_dshot_burst_mode(uint8_t timer, unsigned dshot_pwm_freq, uint8_
|
||||
rEGR(timer) = ATIM_EGR_UG;
|
||||
|
||||
// find the lowest channel index for the timer (they are not necessarily in ascending order)
|
||||
unsigned lowest_timer_channel = 4;
|
||||
unsigned lowest_timer_channel = 3;
|
||||
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;
|
||||
|
||||
@@ -619,13 +619,13 @@ int io_timer_set_dshot_burst_mode(uint8_t timer, unsigned dshot_pwm_freq, uint8_
|
||||
uint32_t start_ccr_register = 0;
|
||||
|
||||
switch (lowest_timer_channel) {
|
||||
case 1: start_ccr_register = TIM_DMABASE_CCR1; break;
|
||||
case 0: start_ccr_register = TIM_DMABASE_CCR1; break;
|
||||
|
||||
case 2: start_ccr_register = TIM_DMABASE_CCR2; break;
|
||||
case 1: start_ccr_register = TIM_DMABASE_CCR2; break;
|
||||
|
||||
case 3: start_ccr_register = TIM_DMABASE_CCR3; break;
|
||||
case 2: start_ccr_register = TIM_DMABASE_CCR3; break;
|
||||
|
||||
case 4: start_ccr_register = TIM_DMABASE_CCR4; break;
|
||||
case 3: start_ccr_register = TIM_DMABASE_CCR4; break;
|
||||
}
|
||||
|
||||
rDCR(timer) = start_ccr_register | tim_dma_burst_length;
|
||||
@@ -934,9 +934,9 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
|
||||
|
||||
/* configure the channel */
|
||||
|
||||
uint32_t shifts = timer_io_channels[channel].timer_channel - 1;
|
||||
uint32_t shifts = timer_io_channels[channel].timer_channel;
|
||||
|
||||
/* Map shifts timer channel 1-4 to 0-3 */
|
||||
/* Map shifts timer channel 0-3 */
|
||||
|
||||
uint32_t ccmr_offset = STM32_GTIM_CCMR1_OFFSET + ((shifts >> 1) * sizeof(uint32_t));
|
||||
uint32_t ccr_offset = STM32_GTIM_CCR1_OFFSET + (shifts * sizeof(uint32_t));
|
||||
@@ -1047,7 +1047,7 @@ int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, io_timer_chann
|
||||
for (int chan_index = 0; masks != 0 && chan_index < MAX_TIMER_IO_CHANNELS; chan_index++) {
|
||||
if (masks & (1 << chan_index)) {
|
||||
masks &= ~(1 << chan_index);
|
||||
uint32_t shifts = timer_io_channels[chan_index].timer_channel - 1;
|
||||
uint32_t shifts = timer_io_channels[chan_index].timer_channel;
|
||||
uint32_t timer = channels_timer(chan_index);
|
||||
action_cache[timer].base = io_timers[timer].base;
|
||||
action_cache[timer].ccer_clearbits |= CCER_C1_INIT << (shifts * CCER_C1_NUM_BITS);
|
||||
|
||||
@@ -166,7 +166,7 @@ led_pwm_channel_init(unsigned channel)
|
||||
{
|
||||
/* Only initialize used channels */
|
||||
|
||||
if (led_pwm_channels[channel].timer_channel) {
|
||||
if (led_pwm_channels[channel].gpio_out) {
|
||||
|
||||
unsigned timer = led_pwm_channels[channel].timer_index;
|
||||
|
||||
@@ -177,22 +177,22 @@ led_pwm_channel_init(unsigned channel)
|
||||
|
||||
/* configure the channel */
|
||||
switch (led_pwm_channels[channel].timer_channel) {
|
||||
case 1:
|
||||
case 0:
|
||||
rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) | GTIM_CCMR1_OC1PE;
|
||||
rCCER(timer) |= polarity | GTIM_CCER_CC1E;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE;
|
||||
rCCER(timer) |= polarity | GTIM_CCER_CC2E;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE;
|
||||
rCCER(timer) |= polarity | GTIM_CCER_CC3E;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE;
|
||||
rCCER(timer) |= polarity | GTIM_CCER_CC4E;
|
||||
break;
|
||||
@@ -226,19 +226,19 @@ led_pwm_servo_set(unsigned channel, uint8_t cvalue)
|
||||
|
||||
|
||||
switch (led_pwm_channels[channel].timer_channel) {
|
||||
case 1:
|
||||
case 0:
|
||||
rCCR1(timer) = value;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
rCCR2(timer) = value;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
rCCR3(timer) = value;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
rCCR4(timer) = value;
|
||||
break;
|
||||
|
||||
@@ -260,25 +260,25 @@ unsigned led_pwm_servo_get(unsigned channel)
|
||||
|
||||
/* test timer for validity */
|
||||
if ((led_pwm_timers[timer].base == 0) ||
|
||||
(led_pwm_channels[channel].timer_channel == 0)) {
|
||||
(led_pwm_channels[channel].gpio_out == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* configure the channel */
|
||||
switch (led_pwm_channels[channel].timer_channel) {
|
||||
case 1:
|
||||
case 0:
|
||||
value = rCCR1(timer);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
value = rCCR2(timer);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
value = rCCR3(timer);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
value = rCCR4(timer);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -93,29 +93,27 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
|
||||
{
|
||||
timer_io_channels_t ret = initIOTimerGPIOInOut(timer, pin);
|
||||
|
||||
ret.timer_channel = (uint8_t)timer.channel;
|
||||
|
||||
switch (timer.channel) {
|
||||
case Timer::Channel1:
|
||||
ret.ccr_offset = STM32_GTIM_CCR1_OFFSET;
|
||||
ret.masks = GTIM_SR_CC1IF | GTIM_SR_CC1OF;
|
||||
ret.timer_channel = 1;
|
||||
break;
|
||||
|
||||
case Timer::Channel2:
|
||||
ret.ccr_offset = STM32_GTIM_CCR2_OFFSET;
|
||||
ret.masks = GTIM_SR_CC2IF | GTIM_SR_CC2OF;
|
||||
ret.timer_channel = 2;
|
||||
break;
|
||||
|
||||
case Timer::Channel3:
|
||||
ret.ccr_offset = STM32_GTIM_CCR3_OFFSET;
|
||||
ret.masks = GTIM_SR_CC3IF | GTIM_SR_CC3OF;
|
||||
ret.timer_channel = 3;
|
||||
break;
|
||||
|
||||
case Timer::Channel4:
|
||||
ret.ccr_offset = STM32_GTIM_CCR4_OFFSET;
|
||||
ret.masks = GTIM_SR_CC4IF | GTIM_SR_CC4OF;
|
||||
ret.timer_channel = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user