io timer: remove some fields from io_timers_t and split out channel indexes

- reduces amount of board configuration required
- removes the cyclic dependency between io_timers_t and timer_io_channels_t

Fixes a bug in the fmuk66-v3 config: the 2. timer has 3 channels associated
not 2.
Fixes a bug in the modelai config: the 2. timer has 4 channels associated.
This commit is contained in:
Beat Küng
2020-02-13 03:49:16 -08:00
committed by David Sidrane
parent 8020e82c1c
commit 62b4f3487a
28 changed files with 581 additions and 301 deletions
@@ -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);
@@ -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);
}
@@ -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
@@ -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);
}
@@ -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
@@ -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;
@@ -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);
@@ -59,6 +59,16 @@
#include <stm32_gpio.h>
#include <stm32_tim.h>
static int io_timer_handler0(int irq, void *context, void *arg);
static int io_timer_handler1(int irq, void *context, void *arg);
static int io_timer_handler2(int irq, void *context, void *arg);
static int io_timer_handler3(int irq, void *context, void *arg);
static int io_timer_handler4(int irq, void *context, void *arg);
static int io_timer_handler5(int irq, void *context, void *arg);
static int io_timer_handler6(int irq, void *context, void *arg);
static int io_timer_handler7(int irq, void *context, void *arg);
#if defined(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);
}