Alex
I didn't understand fully the first timer requirement - if you try it but have difficulties, explain what is not working as it should (and how it is required) and I'll take a look at it.
It is possible to have a periodic timer interrupt for a FlexTimer (or TPM) plus additional channel interrupts; or channel DMA triggers.
Take a look at the DMX512 code in DMX512.c in the uTasker application, and its function fnConfigDMX_framing() [I have copied it below as it is today]. This is used to generate a DMX512 frame period, plus two two interrupts from channel which fire at defined points in the frame (I have also used DMA to trigger events at the same points when really accurate timing is needed). The diagram on page 5 of the attached DMX512 document (the document is in progress and so is provisional) shows the timing.
static void fnConfigureDMX512_framing(void)
{
// Set up a periodic timer to control the frame rate
// - this method is suitable for kinetis parts using a PWM channel to control the break and period, plus a second channel to define the MAB
//
// TPM1 setup
//
PWM_INTERRUPT_SETUP pwm_setup;
pwm_setup.int_type = PWM_INTERRUPT;
pwm_setup.int_handler = 0;
#if defined FRDM_K64F
pwm_setup.pwm_reference = (_TIMER_0 | 0); // timer module 0, channel 0
pwm_setup.pwm_mode = (/*PWM_SYS_CLK | */PWM_PRESCALER_128 | PWM_EDGE_ALIGNED | PWM_POLARITY/* | PWM_NO_OUTPUT*/); // clock PWM timer from the system clock with /16 pre-scaler (don't configure teh clock until all channels are set up)
pwm_setup.pwm_frequency = (unsigned short)PWM_TIMER_US_DELAY(DMX512_PERIOD, 128); // generate frame rate frequency on PWM output
#else
pwm_setup.pwm_mode = (PWM_SYS_CLK | PWM_PRESCALER_32 | PWM_EDGE_ALIGNED | PWM_POLARITY/* | PWM_NO_OUTPUT*/); // clock PWM timer from the system clock with /32 pre-scaler
pwm_setup.pwm_reference = (_TPM_TIMER_1 | 0); // timer module 1, channel 0
#if defined _WINDOWS
pwm_setup.pwm_mode |= PWM_PRESCALER_128;
pwm_setup.pwm_frequency = (unsigned short)PWM_TPM_CLOCK_US_DELAY(DMX512_PERIOD, 128); // generate frame rate frequency on PWM output
#else
pwm_setup.pwm_frequency = (unsigned short)PWM_TPM_CLOCK_US_DELAY(DMX512_PERIOD, 32); // generate frame rate frequency on PWM output
#endif
#endif
pwm_setup.pwm_value = ((pwm_setup.pwm_frequency * DMX512_MASTER_BREAK_DURATION)/DMX512_PERIOD); // output starts low (inverted polarity) and goes high after the break time
pwm_setup.int_priority = PRIORITY_HW_TIMER; // interrupt priority of cycle interrupt
pwm_setup.pwm_mode |= PWM_CHANNEL_INTERRUPT; // use channel interrupt to stop the break
pwm_setup.channel_int_handler = _mab_start_interrupt;
START_DMX512_MASTER_BREAK(); // generate the first break immediately
fnConfigureInterrupt((void *)&pwm_setup); // configure and start
#if defined FRDM_K64F
pwm_setup.pwm_reference = (_TIMER_0 | 1); // timer module 0, channel 1
pwm_setup.pwm_mode |= (PWM_SYS_CLK); // configure the clock so that all channels are ready at start
#else
pwm_setup.pwm_reference = (_TPM_TIMER_1 | 1); // timer module 1, channel 1
#endif
pwm_setup.pwm_value = ((pwm_setup.pwm_frequency * (DMX512_MASTER_BREAK_DURATION + DMX512_MASTER_MAB_DURATION))/DMX512_PERIOD); // second channel goes high after the MAB period to control the timing for the start of the frame transmission
pwm_setup.int_handler = _frame_interrupt; // interrupt call-back on PWM cycle
pwm_setup.channel_int_handler = _mab_stop_interrupt;
fnConfigureInterrupt((void *)&pwm_setup); // configure and start
}
The use s not described in the HW timer document (yet) but it is simple to use - just add the flag PWM_CHANNEL_INTERRUPT and a a callback to channel_int_handler.
Regards
Mark