Hi,
I want to know the timer resolution of the capture mode of FTM module of MK22FN512VLL12. Reference manual specifies 16 bit resolution but this microcontroller has 32 bit timers as well so is it possible to use capture functionality with 32 bit timer resolution? My end goal is to measure frequency of an external signal using capture module with 32 bit resolution for higher accuracy.
Thanks and best regards,
Prasanna
Hi Prasanna Naik
No, The FTM module has a 16-bit counter. You can use the overflow flag to detect this condition and then continue counting.
Best regards
Jorge Alcala
Hi
It is possible to use port pin DMA to trigger transfer of present PIT value to SRAM. This will give samples with 32 bit width and so allow capturing over long periods.
See also chapter 9 of http://www.utasker.com/docs/uTasker/uTaskerHWTimers.PDF
Regards
Mark
Nice, I haven't tried that one before. Someone should start a cookbook of weird things you can do with the DMA controller. I was kind of proud of my 8-to-24-bit lookup table hack, but it's not the most efficient thing.
I'm always using relatively low pin count devices so there's usually at least one UART available that's not bonded out on the package and you can put the UART into loopback mode and enable the match address feature to watch for a particular value and generate an interrupt. What I was trying to do was to get an interrupt when a long-running SPI flash erase operation was completed, with the polling handled entirely by the DMA controller. Didn't quite get there because of limitations of the match address feature, but I thought it was a fun use of undocumented hardware.
Scott
Here are three references:
1. Generating a square wave output from PIT (or two in complimentary pair)
2. Decoding RC5 IR protocol (8x oversampling of pulses to a buffer for subsequent analysis)
3. Port mirroring (toggling other ports based on a signal on an input port).
Regards
Mark
1. (method integrated in uTasker PIT interface)
void fnPitFreqGen(void)
{
PIT_SETUP pit_setup; // PIT interrupt configuration parameters
pit_setup.int_type = PIT_INTERRUPT;
pit_setup.int_handler = 0; // no interrupt due to DMA
pit_setup.ucPIT = 0; // use PIT0
pit_setup.count_delay = PIT_US_DELAY(1); // 1us period (for 500kHz square wave)
pit_setup.mode = (PIT_PERIODIC | PIT_OUTPUT_DMA_TRIG); // periodic with DMA trigger to control a port toggle
pit_setup.ulPortBits = (PORTA_BIT1 | PORTA_BIT2); // toggle PTA1 and PTA2 on each PIT trigger
pit_setup.ucPortRef = PORTA;
fnConfigureInterrupt((void *)&pit_setup); // configure PIT
}
2. (uses uTasker PIT interface and DMA buffer interface)
#define BIT_LENGTH 1800 // bit length in microseconds
#define SAMPLES_PER_BIT 8
#define NR_OF_RC5_BYTES 14
#define RC5_SAMPLES (NR_OF_RC5_BYTES * SAMPLES_PER_BIT)
static unsigned long ulSampleBuffer[RC5_SAMPLES] = {0};
void fnReadRC5(void)
{
PIT_SETUP pit_setup; // PIT interrupt configuration parameters
pit_setup.int_type = PIT_INTERRUPT;
pit_setup.int_handler = 0; // no interrupt due to DMA
pit_setup.ucPIT = 1; // use PIT1
pit_setup.count_delay = PIT_US_DELAY(BIT_LENGTH / SAMPLES_PER_BIT); // sample rate
pit_setup.mode = (PIT_PERIODIC); // periodic
pit_setup.ucPortRef = PORTC;
fnConfigureInterrupt((void *)&pit_setup); // configure PIT
// Note that PIT channel number must match with the DMA channel (hardware requirement) and the DMA channel is chosen here to match the PIT
//
fnConfigDMA_buffer(pit_setup.ucPIT, (DMAMUX0_DMA0_CHCFG_SOURCE_PIT0 + pit_setup.ucPIT), sizeof(ulSampleBuffer), (unsigned long *)(GPIO_BLOCK + (0x040 * pit_setup.ucPIT) + 0x010), ulSampleBuffer, (DMA_DIRECTION_INPUT | DMA_LONG_WORDS | DMA_NO_MODULO), DMA_handler, 2); // source is the GPIO input register and destination is the buffer
fnDMA_BufferReset(pit_setup.ucPIT, DMA_BUFFER_START);
}
// Interrupt when a complete input has been received
//
static void DMA_handler(void)
{
fnInterruptMessage(TaskToWake, REMOTE_CONTROL_EVENT); // inform that the buffer is ready for RC5 decoding
}
3. (uses uTasker port interrupt/DMA interface and DMA buffer interface)
static void fnPortMirrors(void)
{
static const unsigned long ulOutput = (PORTC_BIT16 | PORTC_BIT17); // the outputs to be mirrored to
INTERRUPT_SETUP interrupt_setup; // interrupt configuration parameters
interrupt_setup.int_type = PORT_INTERRUPT; // identifier to configure port interrupt
interrupt_setup.int_port = PORTB; // the port that the interrupt input is on
interrupt_setup.int_port_bits = PORTB_BIT16; // UART input pin on FRDM-K64F
interrupt_setup.int_port_sense = (IRQ_BOTH_EDGES | PULLUP_ON | PORT_DMA_MODE | PORT_KEEP_PERIPHERAL); // DMA on both edges and keep peripheral function
interrupt_setup.int_handler = 0; // no interrupt handler when using DMA
// Configure the DMA trigger from the UART input pin change to toggle an alternative port so that the input signal is mirrored to that output without CPU intervention
//
fnConfigDMA_buffer(9, DMAMUX0_CHCFG_SOURCE_PORTB, sizeof(ulOutput), (void *)&ulOutput, (void *)&(((GPIO_REGS *)GPIOC_ADD)->PTOR), (DMA_FIXED_ADDRESSES | DMA_LONG_WORDS), 0, 0); // use DMA channel 9 without any interrupts (free-runnning)
}