Embedded Signal
Processing
Project 2: GPIO and DAC
Overview
M.S. students randomized
groups of two each week, never working with same student, unless
otherwise directed by instructor.
Ph.D. students have option to choose their groups (all Ph.D. or
mix), with or without randomization.
The objective of this project is to become familiar with:
NOTE: Use the Project Report Template and see below
for minimum required data content
your reports and demos.
IN NO CASE may code or files or data or pictures be exchanged
between student groups, there is to be NO COPYING of group
reports!
Also, each student must be able to independently
answer any questions themselves during demos.
All students are expected to learn all aspects of every project.
Nevertheless, students are encouraged to collaborate (not copy)
during the lab sessions.
- Some technical notes:
- The FRDMK64F board uses the 100-pin MK64FN1M0VLL12
MCU, with
- maximum operation frequency of 120 MHz, 1 MB of flash, 256
KB RAM,
- full-speed USB controller, Ethernet controller
- 12-bit DAC (see pin DAC0_out on the Arduino header)
- 16-bit ADC (see pins A0 to A5 on the Arduino header)
- 68 GPIO (see pins AD0 to AD15 on the Arduino header)
- The 100-pin package on the FRDMK64F has one DAC module, the 121-pin and
144-pin packages have two DAC modules.
- Visit mbed-src
to see the details of DigitalOut.h which resides in the mbed
library
Part 1, GPIO (general-purpose input/output) Programming
- See below for minimum required data
content for your reports and your demos
- In this part, programming the GPIO (general-purpose
input/output) digital ports on the FRDMK64F using mbed IDE is
investigated
- First, create and run the the gpio example code as follows:
- Log into your mbed.org
account
- Go to the mbed
compiler view
- Create a new program using Mbed::MenuBar::NewProgram (blue
arrow below) and
- selecting the FRDM-K64F platform,
- gpio example program template,
- and name frdm_dacGpio01 (blue circle below) as shown below
Fig. 1
- Open the Program Folder and double-click main.cpp (blue
arrow below) to open the main program file as shown below
Fig. 2
- Inspect the main.cpp program code (use main.cpp tab in blue
circle above)
- Click the Mbed::MenuBar::Compile button (red arrow above)
- Make sure that you observe
"success" for the compilation at the bottom of the mbed
window, as before
- Also, note that the file "ffrdm_whateverYourFileName.bin"
should have been downloaded to your computer
- Plug in your FRDM-K64F board
- Open two file-browsers, file-managers, file-navigators, or
finders (depending on what your operating system calls them)
- One file-browser should be opened to the USB device
corresponding to your FRDM-K64F
- The second file-browser should be opened to the directory
containing your dowloaded binary frdm_blinky01_K64F.bin
- In the two file-browsers, drag frdm_whateverYourFileName.bin
into your FRDM-K64F
- On some Apple/Mac setups, it may be necessary to transfer
the file to the FRDM-K64F board using a command line from a
terminal, try:
- sudo mount -u -w -o sync /Volumes/MBED ;cp -X
/Users/tpw/Downloads/tp_frdm_Gain8negCap_02_1us_K64F.bin
/Volumes/MBED/
- Similarly, some programs may require communication through
a terminal (such as a printf() statement in a program)
- For future reference, if a terminal is needed for
input/output (it is not needed now) on an Apple/Mac, open
a new command terminal and run the command:
- screen /dev/tty.usbmodem1412 9600screen
/dev/tty.usbmodem1412 9600
- use the command "ls /dev | grep usb" to make
sure of the name of your usb before running the screen
command above
- When you drag the file, the green LED near the USB port on
the FRDM-K64F should flash as the program is loaded
- Press the reset button near the usb port, and the red LED
should flash
- Create and run the GPIO project code as follows:
- Delete any .bin file that was compiled above and downloaded
to your computer, since we will next replace the default
gpio_example with our own code
- Next: edit the code in the main.cpp frame of the mbed
compiler, as follows
#include "mbed.h"
DigitalOut gpo(D0);
DigitalOut led(LED_RED);
int main()
{
while (true) {
gpo = !gpo; //
toggle pin
// led = !led; //
toggle led
// wait(2.2f);
}
}
- Note that the command "gpo = !gpo;" uses the "operator="
function to implement the "=" sign. To see this, open
the DigitalOut class (red arrow below)
Fig. 3a
- Visit mbed-src
to see the details of DigitalOut.h which resides in the mbed
library
- Even more instructive to see DigitalOut.h:
- Export your project as a zip archive using right-click the
program folder in mbed, exportProgram, k64fTarget,
toolchainZipArchiveWithRepositories
- Unzip the archive that is downloaded
- Navigate to the mbed folder to inspect all the header
files and definitions within them
- Using the oscilloscope,
- connect the "gnd" pin on the Arduino header to the
oscilloscope ground clip,
- measure the gpio signal on the D0 pin
- You should see a digital signal as follows
Fig. 4
- What is the frequency of the square wave above in MHz?
- Each cycle consists of a "1" and "0" data bit, so the data
rate in bits/s is twice the frequency of the square
wave. (this is data rate R1
in your report)
- Next, faster gpio access will be accomplished by using
lower-level code to write directly to the gpio registers
- We will directly set the PDOR Port Data Output
Register, that is a component of the PTC base address.
- The PDOR is described in section 55.2.1, page 1761, of
the K64
Sub-Family Reference Manual, Rev. 2, January 2014
- The PTC is a pointer to "Port C" is described in
MK64F12.h
- To see MK64F12.h :
- Export your project as a zip archive using right-click
the program folder in mbed, exportProgram, k64fTarget,
toolchainZipArchiveWithRepositories
- Unzip the archive that is downloaded
- Navigate to the mbed/TARGET_K64F folder to inspect the
header file and definitions within
- PTC corresponds to memory location 0x400FF080 (see
GPIOC_PDOR on the GPIO memory map table on page 1760 of
the K64
Sub-Family Reference Manual, Rev. 2, January 2014)
- To test this faster access, edit the code in the main.cpp
frame of the mbed compiler, as follows
#include "mbed.h"
DigitalOut gpo(D0);
DigitalOut led(LED_RED);
int main()
{
uint32_t mask16=1<<16;
uint32_t dat1=(PTC->PDOR) | mask16;
//set
uint32_t dat0=(PTC->PDOR) &
(!mask16); //clear
while (true) {
//example
using write to a single bit, DOarduino=PTC16
(PTC->PDOR)=dat0; //clear
(PTC->PDOR)=dat1; //set
(PTC->PDOR)=dat1; //set
(PTC->PDOR)=dat1; //set
(PTC->PDOR)=dat1; //set
(PTC->PDOR)=dat0; //clear
(PTC->PDOR)=dat0; //clear
(PTC->PDOR)=dat1; //set
(PTC->PDOR)=dat1; //set
(PTC->PDOR)=dat0; //clear
//gpo = !gpo; //
toggle pin
// led = !led; // toggle
led
//
wait(2.2f);
}
}
- Compile and run the code
- You should observe an output on your oscilloscope as
follows:
Fig. 5
- The observed output may be sharper if your oscilloscope and
probes have higher bandwidth capability
- The region between the red arrow and yellow arrow above
corresponds to the 4 consecutive "set" commands writing 4
consecutive 1's to the gpio port
- Based on the time between the red (10 percent of peak
voltage) and yellow(90 percent of peak voltage) arrows, how
long did it take to execute each of the 4 "set" commands?
- What is the data rate in bits/second? (this is data rate R2 in your report)
- How much faster is this new gpio method than the method in
Fig. 3?
- The region in the red circle corresponds to time for the
first and last "clear" commands, but also requires extra time
for the execution of the assembly-language branching command
that corresponds to "while loop" in the program. You may
wish to use the debugger to see assembly language listings and
better understand the timing issues
- The mbed-based result of Fig. 4 is likely to be much slower
than the low-level code results of Fig. 5 because of the time
taken in procedure/subroutine calls that are embedded in the
code that implements the mbed-based write operation. Use
of debug disassembly tools may allow you to trace through and
see the differences in the assembly codes and number of
instructions executed.
- To read input from pin D1 try the code below
- This code should change the color of the led,
depending on whether logic 0 or 1 is seen at pin D1
- Pin D0 is set to 0, so connecting pin D0 to D1 should change
the led color
#include "mbed.h"
//#include "MK64F12.h"
DigitalOut gpo(D0);
DigitalIn gpi(D1);
DigitalOut ledred(LED_RED);
DigitalOut ledblue(LED_BLUE);
int main()
{
gpo = 0; // set D0=0
uint32_t D1in=0;
uint32_t mask17=1<<17;
while(1) {
//D1in =
(PTC->PDIR) & mask17; this doesnt seem to work?
wait(0.5f);
if(((PTC->PDIR) & mask17)==0) {
ledblue=1; //set red red if pin D1=0
ledred=0;
} else {
ledblue=0;
ledred=1; //Blue }
}
}
}
Part 2, DAC Programming
- See below for minimum required data
content for your reports and your demos
- In this part, programming the 12-bit DAC on the FRDMK64F using
mbed IDE is investigated
- Create and run the project code as follows:
- Inspect the main.cpp program code (use main.cpp tab in blue
circle above)
- Delete any bin file that was downloaded to your
computer, since we will next replace the default gpio_example
with our own code
- First, the mbed AnalogOut library will be used to write DAC
output
- Delete all of the code in the main.cpp frame of the mbed
compiler, and insert the following new program code into
main.cpp
#include "mbed.h"
DigitalOut gpo(D0);
DigitalOut led(LED_RED);
AnalogOut dac0out(DAC0_OUT);
int main()
{
uint32_t mask16=1<<16;
//PDOR is Port Data Output Register,
offset: 0x0
uint32_t dat1=(PTC->PDOR) | mask16;
//set
uint32_t dat0=(PTC->PDOR) &
(!mask16); //clear
while (true)
{
(PTC->PDOR)=dat0; //clear use data bit as a
timing flag/marker for oscilloscope
(PTC->PDOR)=dat1; //set
for(int
nn=0;nn<6;nn++)
{
dac0out=(0.1f*nn);
//DAC0->DAT[0].DATL = (uint8_t)((uint16_t)(500+
200*nn) & 0xFF);
//DAC0->DAT[0].DATH = (uint8_t)(((uint16_t)(500+
200*nn) >> 8) & 0x0F);
wait((float)(0.001e-6));
}
(PTC->PDOR)=dat0; //clear
}
}
- Compile and run the code
- Connect a second oscilloscope probe to "dac0_out" pin on the
Arduino header
- You should observe an output on your oscilloscope as
follows:
Fig. 6
- For this high-level mbed library method, what is the DAC
speed in samples/second? (this is
frequency F1 in your report)
- As for the GPIO, low-level writes to the DAC are faster
- To see this, change the code as follows
- Delete all of the code in the main.cpp frame of the mbed
compiler, and insert the following new program code into
main.cpp
#include "mbed.h"
DigitalOut gpo(D0);
DigitalOut led(LED_RED);
AnalogOut dac0out(DAC0_OUT);
int main()
{
//usually do not need the following
few initialization lines
//DAC0->C0 = 0; //reset state
//DAC0->C1 = 0;
//DAC0->C0 =
DAC_C0_DACEN_MASK // Enable
// |
DAC_C0_DACSWTRG_MASK // Software Trigger
//
|
DAC_C0_DACRFS_MASK; // VDDA selected
uint32_t mask16=1<<16;
//PDOR is Port Data Output Register,
offset: 0x0
uint32_t dat1=(PTC->PDOR) | mask16;
//set
uint32_t dat0=(PTC->PDOR) &
(!mask16); //clear
while (true)
{
(PTC->PDOR)=dat0; //clear use data bit as a
timing flag/marker for oscilloscope
(PTC->PDOR)=dat1; //set
for(int
nn=0;nn<6;nn++)
{
//dac0out=(0.1f*nn);
DAC0->DAT[0].DATL = (uint8_t)((uint16_t)(500+
500*nn) & 0xFF);
DAC0->DAT[0].DATH = (uint8_t)(((uint16_t)(500+
500*nn) >> 8) & 0x0F);
wait((float)(0.001e-6));
}
(PTC->PDOR)=dat0; //clear
}
}
- Compile and run the code
- You should observe an output on your oscilloscope as
follows:
Fig. 7
- For this low-level mbed library method, what is the DAC
speed in samples/second? (this is
frequency F2 in your report)
- For information on the low-level DAC writing:
- See section 37.4.1 and 37.4.1 page 911 of the K64
Sub-Family Reference Manual, Rev. 2, January 2014
- DAC0 is defined as memory address 0x400CC000 in MK64F12.h
- The DAC0 is a pointer to the DAC0 memory registers
and is described in MK64F12.h
- To see MK64F12.h :
- Export your project as a zip archive using right-click
the program folder in mbed, exportProgram, k64fTarget,
toolchainZipArchiveWithRepositories
- Unzip the archive that is downloaded
- Navigate to the mbed/TARGET_K64F folder to inspect the
header file and definitions within
Report Data
- Minimum required data content for
your report and demos
- Required theory content:
- Required software code excerpt content:
- Main.cpp code to do low-level write to the DAC (just the
for-loop portion of code)
- Required tabular data content:
- The four measured frequencies/data-rates for:
- Mbed-level code GPIO data rate R1 as defined above
- Low-level code GPIO data rate R2 as defined above
- Mbed-level code DAC data rate F1 as defined above
- Low-level code DAC data rate F2 as defined above
- Required pictures/photos content:
- Legible picture (if pdf of your report is
"zoomed/magnified") showing mbed-level slow GPIO as in
Fig. 4 and low-level fast GPIO as in Fig. 5 (as roughly
illustrated illegibly below on the left)
- Legible picture (if pdf of your report is
"zoomed/magnified") showing mbed-level slow DAC as in Fig. 6
and low-level fast DAC as in Fig. 7 (as roughly
illustrated illegibly below on the right)
- Project Demos
- Be prepared to demonstrate and discuss items such as:
- Demonstrate an low-level fast GPIO
- Demonstrate an mbed-level slow GPIO
- Change the data for any GPIO
- Discuss the data rate
- Demonstrate an low-level fast DAC
- Demonstrate an mbed-level slow DAC
- Change the data for any DAC
- Be prepared to answer questions such as:
- Demonstrate a full clean/build
- What port number is D0 (PT???)
- What port number is D5 (PT???)
- Wait (1.0e-3) waits for how long?
- What operator in AnalogOut.h is used in the code line "gpo
= !gpo; "
- What is a header file?
- What is PDOR?
- What does PTC->PDOR mean?
- What is the base address of PTC?
- Is "gpo" an object or a class? or is it an integer?
Report:
- See above project description for required
report data content.
- NOTE Report Template Use the Project Report Template
( embDspProjTemplate.docx) for your report.
- One pdf-format must be emailed to the instructor at the
beginning of the class meeting of the demo.
- One hardcopy per student, plus
one extra hardcopy for the instructor, should be brought to
class for the demo.
- Do not add extraneous pages or put explanations on separate
pages unless specifically directed to do so. The instructor will
not read extraneous pages!
- YOU MUST ADD CAPTIONS AND FIGURE NUMBERS TO ALL FIGURES!!
Copyright 2015 T. Weldon
Freescale, Kinetis are registered trademarks of Freescale
Semiconductor, Inc. Texas Instruments, TI, C2000, and
Code Composer Studio are a registered trademarks of Texas
Instruments Incorporated. Adafruit is a registered
TradeMark of Limor Fried. ARM, Cortex and Keil are
registered trademarks of ARM Limited (or its subsidiaries).
Apple, Yosemite, Mac OS, iPhone, iPad, MacBook, Mac, iTunes, and
Xcode are trademarks of Apple inc. All other product or service
names are the property of their respective owners. Arduino
is a registered trademark of Arduino.