Setting up and utilizing a DMA timer to measure frequency
Posted: Tue Jul 28, 2009 1:29 pm
Using a DMA timer to measure frequency application note
Introduction
The 32-bit Direct Memory Access (DMA) timers can be used to measure input by comparing the system clock when you begin the timer and when you exit the timer. It can also measure input through DTIN. We will be providing the input we want to count, so we will use DTIN in this example. Using this method, you can measure the frequency of an incoming signal. In this example, we will be measuring the frequency of light using a light->frequency IC, along with a MOD5282 module.
This example source can be ported to any module with a dma timer, but the example source may vary depending on module. The methods described in step 2 will help you port this to any module.
This application note has 3 steps that we will cover.
1. Attaching the hardware
2. Referencing the Motorola Processor Manual to set up the timer
3. Reading the output
Parts List
Part Name
Part Code
Supplier
Price
NetBurner MOD5282 Development Kit
NNDK-MOD5282-KIT
http://www.netburnerstore.com
$299
TSL230R Light Intensity to Frequency IC
SEN-08940
http://www.sparkfun.com
$5.95
Attaching the hardware
The TSL230R


To make the code easier to read and easier to understand, I like to define the MOD5282 pins I am going to be using to be the same as the pins on the TSL230R. A few define statements will do this:
As you can see in the code above, the pins that we need should now be plugged into the module. In addition the the connections specified, you should also connect ~OE to GND, GND to GND, and Vdd to VCC. I used some simple, removable wiring to accomplish this. You could also solder the connections onto the prototype area of your carrier board.


Since many of the pins are dual use on the NetBurner module, you should now specify in code that you will be using the pins as GPIO and DTIN0.
s0->s3 are programmable input pins into the TSL230R. Reviewing the data sheet for the TSL230R, we discover that these pins allow us to program the sensitivity and scaling of the device.

I set my options to no scaling and maximum (100x) sensitivity. With the hardware set up, we now need to set up our timer.
Referencing the Motorola Processor Manual to set up the timer
When accessing features of the module processor, it is important to know how to read the reference material. You can always download your module's reference manual at http://www.netburner.com. From the homepage:

Within the MOD5282 product page, select the Freescale Coldfire MCF5282 Manual:

You now have the full power of the MCF5282 User Manual in your hands, or, rather, in your screen.
Since we will be using the DMA timer, scroll through the table of contents to find where the DMA Timer section starts:

Scroll to this section. This is your guide to the DMA timer. The manual typically offers an introduction, features overview, and then gets in to the memory map to configure/read the timer.
NetBurner makes it easy to write to and read these memory maps through use of your module's sim file. Open up sim5282.h in c:\nburn\mod5282\system to follow along. The relevant code is below:
As you can see, a structure is created that corresponds to the memory map described in the MCF5282 manual. Once you include sim.h in your nbeclipse project, you can access this structure with
You may have noticed that timerstruct became timer. If you look further down sim5282.h, you will find it defined to timer when the mcf5282 structure is defined. You also noticed that timer[0] is used. We have 4 timers available, we will only be using the first in this example.
Back to the DMA Timer initialization. In section 21.2.6, you will find the DMA Timer mode registers. This will need to be written to to initialize the timer.

Looking at this chart, we will configure timer[0] to count falling edges read from the DTIN0 pin.
Reading the Output
Now that the module is connected, and the timer0 is initialized, it's time to read output. To get the frequency, we must sample the DTIN0 line for 1 second, counting all the falling edges. Because this example operates without interupts or tasks, I opted to only sample 250ms, and then multiply the result by 4. This will reduce accuracy somewhat.
The readIn() function first syncs to the value of TimeTick. We will use TimeTick to know when our sampling time starts and ends. Within the while statement, we wait for the next TimeTick to occur to start the sample. This puts us on the leading edge of the TimeTick variable. We then wait for 5 ticks to occur. We are using the default TICKS_PER_SECOND = 20, so 5 ticks = 250ms. Once our sample time has ended, we save the amount of falling edges counted on DTIN0 to buffer. This buffer is multiplied by 4 to give us the frequency of the input.
Once we have the frequency, displaying the frequency is a simple iprintf statement.
Open up MTTTY to see your results!

Introduction
The 32-bit Direct Memory Access (DMA) timers can be used to measure input by comparing the system clock when you begin the timer and when you exit the timer. It can also measure input through DTIN. We will be providing the input we want to count, so we will use DTIN in this example. Using this method, you can measure the frequency of an incoming signal. In this example, we will be measuring the frequency of light using a light->frequency IC, along with a MOD5282 module.
This example source can be ported to any module with a dma timer, but the example source may vary depending on module. The methods described in step 2 will help you port this to any module.
This application note has 3 steps that we will cover.
1. Attaching the hardware
2. Referencing the Motorola Processor Manual to set up the timer
3. Reading the output
Parts List
Part Name
Part Code
Supplier
Price
NetBurner MOD5282 Development Kit
NNDK-MOD5282-KIT
http://www.netburnerstore.com
$299
TSL230R Light Intensity to Frequency IC
SEN-08940
http://www.sparkfun.com
$5.95
Attaching the hardware
The TSL230R


To make the code easier to read and easier to understand, I like to define the MOD5282 pins I am going to be using to be the same as the pins on the TSL230R. A few define statements will do this:
Code: Select all
#define s0 (J2[30]) // SPI CS0 / GPIO
#define s1 (J2[40]) // SPI CS1 / GPIO
#define s2 (J2[35]) // SPI CS2 / GPIO
#define s3 (J2[26]) // SPI CS3 / GPIO
#define in (J2[31]) // Analog i/o ch0


Since many of the pins are dual use on the NetBurner module, you should now specify in code that you will be using the pins as GPIO and DTIN0.
Code: Select all
s0.function(PIN_GPIO);
s1.function(PIN_GPIO);
s2.function(PIN_GPIO);
s3.function(PIN_GPIO);
in.function(PINJ2_31_TIN0);

Code: Select all
s0 = 1;
s1 = 1;
s2 = 0;
s3 = 0;
Referencing the Motorola Processor Manual to set up the timer
When accessing features of the module processor, it is important to know how to read the reference material. You can always download your module's reference manual at http://www.netburner.com. From the homepage:

Within the MOD5282 product page, select the Freescale Coldfire MCF5282 Manual:

You now have the full power of the MCF5282 User Manual in your hands, or, rather, in your screen.
Since we will be using the DMA timer, scroll through the table of contents to find where the DMA Timer section starts:

Scroll to this section. This is your guide to the DMA timer. The manual typically offers an introduction, features overview, and then gets in to the memory map to configure/read the timer.
NetBurner makes it easy to write to and read these memory maps through use of your module's sim file. Open up sim5282.h in c:\nburn\mod5282\system to follow along. The relevant code is below:
Code: Select all
typedef struct { /* DMA Timer Module */
vuword tmr; // 0x00 -> 0x01 - DMA Timer Mode Register
vubyte txmr; // 0x02 -> 0x02 - DMA Timer Extended Mode Register
vubyte ter; // 0x03 -> 0x03 - DMA Timer Event Register
vudword trr; // 0x04 -> 0x07 - DMA Timer Reference Register
vudword tcr; // 0x08 -> 0x0B - DMA Timer Capture Register
vudword tcn; // 0x0C -> 0x0F - DMA Timer Counter Register
vubyte pack00[48]; // 0x10 -> 0x3F - RESERVED
} timerstruct; /* 0x00_0400 -> 0x00_04FF - For array timer[4] */
Code: Select all
sim.timer[0].tmr = // value;
Back to the DMA Timer initialization. In section 21.2.6, you will find the DMA Timer mode registers. This will need to be written to to initialize the timer.

Looking at this chart, we will configure timer[0] to count falling edges read from the DTIN0 pin.
Code: Select all
/* Timer0 Configuration
* [PS] - 0x00 No Prescaling
* [CE] - 00 Disable capture event output - Not used
* [OM] - 0 Not using this
* [ORRRI] - 0 Not using interrupts
* [FRR] - 0 Timer continues to increment
* [CLK] - 11 Measuring falling edges on DTIN0 pin
* [RST] - 1 Enable Timer
*
* = 0x0007
*/
sim.timer[0].tmr = 0x0007;
Now that the module is connected, and the timer0 is initialized, it's time to read output. To get the frequency, we must sample the DTIN0 line for 1 second, counting all the falling edges. Because this example operates without interupts or tasks, I opted to only sample 250ms, and then multiply the result by 4. This will reduce accuracy somewhat.
Code: Select all
DWORD readIn() {
DWORD buffer = TimeTick; // Buffer holding current TimeTick
while (buffer+1 > TimeTick);
sim.timer[0].tcn = 0;
while (buffer+1+5 > TimeTick);
buffer = sim.timer[0].tcn; // Buffer holding frequency
return (buffer*4);
}
Once we have the frequency, displaying the frequency is a simple iprintf statement.
Code: Select all
iprintf("freq: %8d\r",i);
