8004.Teaching Precision Data Converters to Speak Stellaris

advertisement
Teaching Precision Data
Converters to speak Stellaris®
Kevin Duke
1
Introduction
• Why Stellaris?
– StellarisWare is a helpful asset for quickly
and easily delivering sample code with
minimal experience on the platform
– Stellaris evaluation boards have on-board
emulation circuitry
– 32 bit ARM Cortex M3 Core
2
Stellaris’ fit in the TI Embedded Portfolio
3
Stellaris’ fit in the TI Embedded Portfolio
4
Introduction
• Why Code Composer Studio?
– One of the many tool-chains that StellarisWare supports
– Easy to use tools to view and export data in memory for
analysis/evaluation
– Dedicated internal support via the E2E Community
5
As simple as 7 lines of code...
6
...and 5 blue wires
DVDD
DVDD
VBD
VDD
ADS7953
CS
SSI0Fss
SDI
SSI0Tx
SDO
SSI0Rx
SCLK
SSI0CLK
BDGMD
LM3S3748
GND
DGND
7
Agenda
• C Review
• Code Composer Studio
• Stellaris Peripherals
• Creating Sample Code
• Questions
8
C Review
- Variable Types, Qualifiers, & Modifiers
- StellarisWare variable naming convention
- Function Prototypes & Definition
9
Variable Declaration & Qualifiers
• <Qualifier/Modifier> <Type Modifier> <Type> <Name>
• Common Qualifiers:
– const indicates a structure or variable that contains a nonmodifiable run-time value
– volatile indicates a structure or variable that is subject to sudden
change and will be excluded from compiler optimization
10
Volatile Keyword Example
tBoolean bNewData = FALSE;
// Flag for new data
while( !bNewData )
{
//Do something else
}
11
Volatile Keyword Example
tBoolean bNewData = FALSE;
// Flag for new data
while( 1 )
{
//Do something else
}
12
Volatile Keyword Example
Volatile tBoolean bNewData = FALSE;
// Flag for new data
while( !bNewData )
{
//Do something else
}
13
Variable Declaration & Modifiers
• <Qualifier/Modifier> <Type Modifier> <Type> <Name>
• Common Modifiers:
– extern indicates that the initial value of a variable or body of a
function is defined in another source file
– static is typically used inside function calls and indicates that the
structure or variable will only be initialized once and its value will be
maintained even when it leaves scope
14
Variable Types & Type Modifiers
• Basic Types:
– char is an 8 bit fixed point allocation
– int is usually a 16 bit fixed point allocation, but should be used with a type
modifier for clarity
– float is a 32 bit ‘single precision’ floating point allocation
– double is a 64 bit ‘double precision’ floating point allocation
• Type Modifiers:
–
–
–
–
–
signed indicates the data format is binary two’s complement
unsigned indicates the data format is straight-binary
short specifies a 16 bit allocation
long specifies a 32 bit allocation or increases allocation size
Note: unsigned short <name> is a valid declaration
15
tBoolean Type
• Bool and Boolean are not keywords in standard C
• tBoolean is an unsigned char typedef created and used heavily
by StellarisWare
• As a good rule of thumb always include inc/hw_types.h in source
utilizing StellarisWare
typedef unsigned char tBoolean;
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
16
Function Prototypes
• Function prototypes tell the compiler what the function
looks like and how it behaves
• Function prototypes follow the pattern:
– <Modifier> <Return Type> <Name>(<Parameters>);
17
Function Prototypes - Examples
• void enablePeripheral(); - A generic enable function
prototype that returns nothing and takes no parameters
• signed short readData(); - A generic read function prototype
that takes no parameters but returns a signed short
• tBoolean writeData(signed short ssData); - A generic
write function prototype that writes a signed short to the serial
peripheral and returns a tBoolean indicating success or failure
18
StellarisWare Naming Convention
• Variable types & return types are made clear in each declaration:
– <type><Name>
• Generic Examples:
–
–
–
–
–
unsigned short usVariable;
unsigned long ulVariable;
signed short ssVariable;
signed long slVariable;
unsigned char * pucVariable;
19
HWREG & Writing to Memory Directly
• A series of HWREG macros are defined in hw_types.h along with the
tBoolean declaration
• HWREG() is a simple macro that type casts values appropriately to be
treated as locations in memory
– Used heavily by StellarisWare and looks scary, but is pretty simple
20
Code Composer Studio
- Creating a Stellaris Project
21
Creating & Configuring a Stellaris Project
• Create a New CCS Project
• Add the Vector Table
• Setup Compiler Include Paths
• Setup Linker Search Paths
• Pre-defined Symbols
22
Create a New Project
• File > New > CCS Project
23
Create a New Project
• CCS Generates:
– Target configuration file for ICDI
– Linker command file
– Empty main file
• What’s here will build cleanly, but it wont run
24
Creating & Configuring a Stellaris Project
• Create a New CCS Project
• Add the Vector Table
• Setup Compiler Include Paths
• Setup Linker Search Paths
• Pre-defined Symbols
25
What is the NVIC?
• Nested Vectored Interrupt Controller
– Part of what makes the ARM Cortex M3!
• The NVIC...
–
–
–
–
–
Enables / Disables interrupts
Sets / Arbitrates interrupt priority
Provides low-latency interrupt processing
Works closely with the processor core for low-power modes
Saves the processor state on entry to any given interrupt
26
What is the Vector Table?
• Maps NVIC events to action carried out by interrupt service routines
• The vector table always carries a unique name in each toolchain/IDE
– In CCS it is called ‘startup_ccs.c’
• How to generate your own vector table
– Copy & Paste a vector table from a sample StellarisWare project or use the
one embedded in this slide
– Create a new source file in CCS, name the file ‘startup_ccs.c’, paste the
contents of the file embedded in this slide
• If using a vector table from a StellarisWare project, make sure that it
doesn’t have any un-needed or undefined ISR referenced
startup_ccs.c
27
The Vector Table
28
Creating & Configuring a Stellaris Project
• Create a New CCS Project
• Add the Vector Table
• Setup Compiler Include Paths
• Setup Linker Search Paths
• Pre-defined Symbols
29
Compiler Include Paths
• The include paths tell the compiler where to look for files external to the CCS
project (i.e. StellarisWare header files!)
• Including source files in an include path does not mean that those files will be
compiled when CCS builds the project
• Project > Properties > Build > ARM Compiler > Include Options
30
Creating & Configuring a Stellaris Project
• Create a New CCS Project
• Add the Vector Table
• Setup Compiler Include Paths
• Setup Linker Search Paths
• Pre-defined Symbols
31
Linker Search Path
• Since included files are not compiled with the rest of the project when CCS
builds the project – instead, pre-built libraries are provided for the linker to
integrate with the project post-compile
• Project > Properties > ARM Linker > File Search Path
32
Creating & Configuring a Stellaris Project
• Create a New CCS Project
• Add the Vector Table
• Setup Compiler Include Paths
• Setup Linker Search Paths
• Pre-defined Symbols
33
Predefined Symbols
• The StellarisWare API is usable by all Stellaris devices, symbol definition is used to help
describe to StellarisWare the environment it is being used in
• Generally there are 3 required definitions
– IDE/Toolchain
– Part Number
– Device Family
• Project > Properties > Build > ARM Compiler > Advanced Options > Predefined Symbols
34
Creating & Configuring a Stellaris Project
• Create a New CCS Project
• Add the Vector Table
• Setup Compiler Include Paths
• Setup Linker Search Paths
• Pre-defined Symbols
• Write Sample Code!
35
Code Composer Studio
- Useful Tools
36
Watch Expressions
• While debugging a project in CCSv5 any variable or data structure can
be added to the ‘Watch Expression’ window to monitor it’s value
• Highlight the variable, right-click, & select ‘Add Watch Expression’
37
Graphing Tools
• Sequential ranges of memory can be graphed & the graphing tool offers a variety of ways
to look at the data
– Assign data format, x-axis, address increment, etc.
• Items in the Watch Expression window can be quickly graphed by selecting the item,
right-click, and select ‘Graph’
– The graph assumes the data-format of the variable or structure being watched & sets address
increment automatically
38
Other Useful Items
• There are a lot of settings available for the compiler and linker in CCS,
summary information is available to streamline debugging:
– Project > Properties > ARM Compiler > Summary of Flags Set:
• -mv7M3 --code_state=16 --abi=eabi -me -g -include_path="C:/TI/ccsv5/tools/compiler/tms470/include" --include_path="C:/StellarisWare" -define=ccs --define=lm3s3748 --define=TARGET_IS_DUSTDEVIL_RA0 --diag_warning=225 -display_error_number
– Project > Properties > ARM Linker > Summary of Flags Set:
• -mv7M3 --code_state=16 --abi=eabi -me -g --define=ccs --define=lm3s3748 -define=TARGET_IS_DUSTDEVIL_RA0 --diag_warning=225 --display_error_number -z -stack_size=256 -m"SummitDemo.map" --heap_size=0 -i"C:/TI/ccsv5/tools/compiler/tms470/lib"
-i"C:/TI/ccsv5/tools/compiler/tms470/include" --reread_libs --warn_sections --rom_model
• Compiler optimization is sometimes not ideal
– Project > Properties > ARM Compiler > Optimization
• Linker options are available to modify stack/heap size:
– Project > Properties > ARM Linker > Basic Options
39
Stellaris Peripherals
-GPIO Basics
40
Stellaris GPIO Essentials
• Nearly all GPIO ports/pins are multiplexed with digital and peripheral
functionality, by default GPIO are under “software control”
• Each GPIO port under software control can be configured:
–
–
–
–
–
Input or Output
Interrupt events
Pull up/down resistors
Open drain enables
Drive strength (up to 18mA, limit 4 per device)
• By default all GPIO, and many other peripherals use the Advanced
Peripheral Bus (APB) bus
41
“Traditional” GPIO Data Access
• What does the following line of code actually do?
– ucSomeVariable |= 0x01;
• Commonly referred to as read-modify-write access
– ucSomeVariable = ucSomeVariable | 0x01;
WRITE
READ
MODIFY
42
GPIO Bit Masking
• Available for both read and write operations
• Alleviates the need for read/modify/write access – increasing speed
• Each data register is virtualized in 256 locations in the memory map,
the address offset from the data address sets the bit mask
43
GPIO Bit Masking
#defines resolved by
pre-processor...
HWREG(GPIO_PORTA_BASE + GPIO_O_DATA + ( GPIO_PIN_0 << 2) = 0x01;
GPIO A Base Address
GPIO A Data Address
GPIO A Data Address
with access only to bit 0
HWREG(0x40004000 + 0x00000000 + ( 0x00000001 << 2) = 0x01;
macros evaluated by
pre-processor...
HWREG(0x40004004) = 0x01;
Single action
masked write
(*((volatile unsigned long *)(0x40004004))) = 0x01;
44
Stellaris Peripherals
-GPIO Acceleration for Parallel Interfaces
45
Accelerating GPIO for Parallel Buses
• Always leverage the GPIO data bit masking features for
read and write access
• StellarisWare APIs are not ideal for controlling a high-speed
parallel bus
– LM3S3748 at 50MHz interfacing the AMC1210 parallel bus takes
~290 clock cycles to do a single byte select 16 bit read using
StellarisWare
• The APB is a congested bus since many peripherals use
this bus
46
Accelerating GPIO for Parallel Buses
• The Advanced High-Performance Bus (AHB) is less congested than
the APB
• AHB access in code behaves the same as using the APB aperture
• Re-write versions of the StellarisWare read/write functions that do not
do anything extra
• LM3S3748 at 50MHz interfacing the AMC1210 parallel bus takes ~30
clock cycles to do a single byte select 16 bit read using HWREG and
the AHB bus
47
Stellaris Peripherals
-Synchronous Serial Interface for SPI Interfaces
48
Synchronous Serial Interface
• Almost all Stellaris devices have the same SSI peripheral
– SCLK: The maximum SCLK frequency is half the system clock or up
to 25MHz in master mode
– Frame Width: 4-16 Bit frames are supported, some can be
combined for larger continuous frames
– Frame Modes: TI SSI (Frame Sync), Motorola/Freescale SPI (Chip
Select), and MICROWIRE (8-bit Half-Duplex)
• Separate TX & RX FIFOs:
– 16 Bits wide
– 8 Locations deep
49
Back-to-Back Frames
• 16 bits will only provide limited coverage over precision data converters
• Frame combination is only allowed in Freescale SPI mode, and is
limited by SSI clock phase
50
Creating Sample Code
- ADS7953 ‘Case Study’
- Where to find digital answers in a Datasheet
- Writing & Validating the Sample Code
51
Getting Started
• Have documentation handy
– Stellaris product datasheet
• This Guide will use the LM3S3748
– Evaluation Board User’s Guide
• Identify available clocking methods
– Stellaris Peripheral Driver Library User’s Guide
• Identify available functions and parameters of StellarisWare API
• Create a Stellaris Project in Code Composer Studio
– Everything is ready and we have a blank main.c
• Include inc/hw_types.h in the project’s main
52
ADS7953 Evaluation Requirements
• Defined by Part:
– Frame Size
– Framing Format
– Critical Edge
• Customer Requests
– Select fastest SCLK possible w/LM3S3748 & ADS7953
– Operate ADS7953 in Manual Mode
53
As simple as 7 lines of code...
54
System Clock
• Derivatives of the system clock will be used to clock every
peripheral on the device
• In documentation and StellarisWare the System Clock is a member
of the System Control library
– System Control also includes device identification, local control, lowpower modes, peripheral enables, and the on-chip LDO
• Providing the system clock from the PLL source provides more
flexibility than the other clocking options & achieves higher speed
– The PLL VCO will be set very close to 400MHz, depending on crystal
value
– PLL VCO frequency is pre-divided to 200MHz, except for high-speed
Stellaris products
• Check if bit 30 (DIV400) in the RCC2 is reserved, this bypasses the predivider
55
Possible PLL Clocking Configurations
• Check the ‘Clock Configuration’ subsection of ‘System Control’ in
the product datasheet
56
Choosing the System Clock
• Customer requests the highest speed possible w/LM3S3748 &
ADS7953
• ADS7953 Max SCLK is 20MHz
• The smallest clock divider from System Clock to SCLK is 2
– With a 50MHz system clock we must settle for 16.6MHz SCLK
– If we settle for a 40MHz system clock we can achieve the max SCLK
57
Setting the System Clock
• Include the appropriate driver for System Control from the
StellarisWare library
– driverlib/sysctl.h
• All available functions of StellarisWare are documented in the
Stellaris Peripheral Driver Library User’s Guide
• void SysCtlClockSet(unsigned long ulConfig)
– ulConfig is a 32 bit wide bit-field for passing values from the system
control header of StellarisWare
• To use the PLL ulConfig is made up of 4 values bitwise OR’d
–
–
–
–
The external crystal frequency
The clock divider setting
SYSCTL_USE_PLL
SYSCTL_OSC_MAIN
58
Values for SysCtlClockSet Parameters
59
As simple as 7 lines of code...
60
Enable GPIO & SSI Peripherals
• Every peripheral in use needs to be enabled first
• Enabling the SSI peripheral alone does not enable the physical
port/pins in use on the device
– The appropriate GPIO port must also be enabled
• void SysCtlPeripheralEnable(unsigned long ulPeripheral)
– ulPeripheral is the value from the system control header for the peripheral
of interest
61
As simple as 7 lines of code...
62
Set GPIO Pin MUX
• Almost every pin on every port can be set for two types of
functionality
– Digital I/O under software control
– Hardware/Peripheral controlled
• GPIO Port & Pin control are part of the GPIO driver of StellarisWare
– #include “driverlib/gpio.h”
• void GPIOPinTypeSSI(unsigned long ulPort, unsigned char ucPins)
– ulPort is the base address of the GPIO port
– ucPins is a bit field representative of the pins in use
63
Missing Peripheral Base Addresses
• Identifier undefined almost always means an include file is missing
• Peripheral base address values are defined in hw_memmap.h
64
As simple as 7 lines of code...
65
What is the Framing Format?
• Chip Select (Motorola/Freescale) – Set for the entire frame
• Frame Sync (TI)– Identifies the beginning of new data
66
Ask the Datasheet
• What is the framing format?
– Check the timing diagram
– Check device pin configuration
67
Ask the Datasheet
• How many bits per frame?
– Check the Device Operation, Overview, and/or Digital Interface sections
– Refer back to the timing diagram
68
Clock Phasing and Polarity
• TI & Freescale SPI each have clock phase and polarity settings
• Polarity describes what the clock looks like when the serial bus is idle
• Polarity = 0
– The clock idles low
• Polarity = 1
– The clock idles high
69
Clock Phasing and Polarity
• Phase describes which clock edge will trigger reads and writes
– Standard interfaces read and write on the same edge
• Phase = 0
– Data is read/written on the first edge (Figure illustrated with Polarity 0)
• Phase = 1
– Data is read/written on the second edge (Figure illustrated with Polarity 0)
70
Clock Phasing and Polarity
• Phase and Polarity together define which edge is the critical edge
– 2 ways to achieve each rising and falling critical edges
71
Clock Phasing and Polarity
• Many devices do not specify clock polarity
– i.e. ADS7953
• Only interested in seeing a rising or falling edge some time after CS
has toggled
72
What is the Critical Edge?
• The critical edge tells us when data may be changing and when data
should be stable for reads & writes
– Sets clock phase and polarity
• MOSI – Master Out Slave In
– Setup Time – How long the data needs to be valid before being clocked in
– Hold Time – How long the data needs to remain valid to guarantee it is
clocked in
– Setup and Hold time on MOSI define the critical edge
• MISO – Master In Slave Out
– Delay Time – How long it takes for the data to settle on the bus
– Hold Time – How long will the data remain on the bus
73
Ask the Datasheet
• Do not just look at the timing diagram to find the critical edge
• Look at MOSI (SDI) to discover the critical edge
74
Configuring the SSI Port
• The SSI port can only be configured while peripheral operation is
disabled
• We’ve enabled clocking to the peripheral but it is still not operational
– the StellarisWare API ensures peripheral operation is disabled when the
peripheral clock is enabled
• SSI control is in the SSI driver of StellarisWare
– #include “driverlib/ssi.h”
• void SSIConfigSetExpClk(...)
–
–
–
–
–
–
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
long
long
long
long
long
long
ulBase – Base address of SSI Module
ulSSIClk – Peripheral Clock Frequency
ulProtocol – Specifies the interface protocol
ulMode – Master or Slave mode
ulBitRate – SCLK Frequency
ulDataWidth – Number of bits per frame
75
As simple as 7 lines of code...
76
Interfacing the Data Converter
• The LM3S3748 is fully configured and ready to interface the
ADS7953
• Create a header file to represent the register settings of the device
– Bit-field values like StellarisWare API parameters
77
Sending and Receiving Data
• StellarisWare API provides blocking and non-blocking functions for
both reads and writes
– Blocking functions wait until there is space or new data in the TX or RX
FIFOs to read data from memory
– Non-blocking functions will simply not read or write data from memory if
there is no space or nothing to read
– Functions not marked “NonBlocking” are blocking
• void SSIDataGet(unsigned long ulBase, unsigned long *pulData)
– ulBase – Base address of the SSI port
– *pulData – Pointer to the location in memory to store the data
• Void SSIDataPut(unsigned long ulBase, unsigned long ulData)
– ulBase – Base address of the SSI port
– ulData – Data to be transmitted on the serial bus
78
Finishing Touches
79
Set Breakpoints, Debug, & Graph
80
For more information...
• Embedded in this presentation are two CCSv5 projects
– ADS7953 in Manual Mode w/StellarisWare
– ADS7953 in Manual Mode w/StellarisWare w/DMA
• Check out the Precision Data Converter Design Notes on the E2E
Community – this presentation will be posted and updated to include
interrupts, uDMA, and deeper coverage for each topic
SummitDemo.zip
SummitDemoDMA.zip
81
Download