How To Use MCBSP
How To Use MCBSP
Introduction
In this module, we will learn how to program the C6000 McBSP using the CSL. First, we’ll learn
how the McBSP operates and the choices we can make, and then how to use the CSL to program
the selected options. In the lab, you will finally use the DSK to make some “noise”. If it sounds
like a song, you got it right. If it really is just noise…then you’ll have some debugging to do…
Learning Objectives
Goals for Module 6…
McBSP EDMA CPU
Rcv gBufRcv
+
ADC RCVCHAN
Xmt COPY
gBufXmt
DAC XMTCHAN
Chapter Topics
McBSP........................................................................................................................................................ 6-1
McBSP Overview
The Multi-Channel Buffered Serial Port (McBSP) is an extremely flexible serial port. The follow
graphic is a humorous approach at describing its many standards and capabilities.
T1
2 SP
M- I
IO
Codecs
AI
Cs
Bu s
ST - MVIP E1
AC’97
IIS
Could this be you? /A-La
w
u-Law nne
l
The McBSP is an extremely a
Full-
duplex -Ch
capable serial port
Mu lti
Block Diagram
The McBSP is a full-duplex, synchronous serial port. Either the CPU or EDMA can read and
write to its memory-mapped data registers (DRR, DXR).
CPU
D R
R Expand B RSR DR
(optional)
I R R 32
n
t D
e Compress
r X (optional) XSR DX
n R
a
l
B CLKR
u CLKX
s
McBSP Control RCR SRGR
SPCR CLKS
Registers XCR PCR
EDMA FSR
FSX
T TO
Technical Training
Organization
FS
D a1 a0 b7 b6 b5 b4 b3 b2 b1 b0
Word
Bit
“Bit” - one data bit per SP clock period
“Word” or “channel” contains #bits
specified by WDLEN1 (8, 12, 16, 20, 24, 32)
Serial Port
SP Ctrl (SPCR) 7 5
Rcv Ctrl (RCR) RWDLEN1
Xmt Ctrl (XCR)
Rate (SRGR) 7 5
Pin Ctrl (PCR) XWDLEN1
FS
D w6 w7 w0 w1 w2 w3 w4 w5 w6 w7
Frame
Word
Their receive and transmit bit-clocks (CLKR, CLKX) can each be setup as either an input or
output pin.
FSR
Input or Output? FSX
CLKR
CLKX
When used as an output, the McBSP generated (CLKG) clock signal can either be divided down
from the C6000’s internal clock or from a separate external clock (CLKS) input.
Frame sync signals can also be generated or input into the McBSP. When generated, you can
define their period and pulse-width. Optionally, the FSX bit can be generated automatically any
time a value is written into the Transmit Serial Register (XSR).
The McBSP’s can generate CPU interrupts for a number of conditions (as shown on the next
page). In this workshop, we will only use (and study) one of these conditions: data ready.
When the receive channel has data ready to be written (i.e. data has moved from RBR to DRR), it
sets the RRDY bit in the Serial Port Control Register (SPCR). This bit can be used to generate an
interrupt to the CPU (RINTx) and/or a trigger event to the EDMA (REVTx).
Similarly, the transmit side of the serial port can set the XRDY bit in the control register and
generate the XINTx and XEVTx interrupt and event, respectively.
McBSP Events/Interrupts
R/XRDY displays “status” of ports:
0: not ready
RBR DRR 1: ready to read/write
It was useful for use to use these two terms in order to differentiate the destination of the various
synchronization signals. While the signals may be generated (and thus sent from) a common
source, the structures in the CPU and EDMA that deal with them are entirely separate & distinct.
As mentioned on the last page, the McBSP can generate CPU interrupts for various
conditions. Shown below are the conditions along with the bit fields used to select which
condition will be used to generate an interrupt.
XRDY
End of Block (XMT)
XINTM New FSX (frame begin)
XINT
Transmit Sync Error
Serial Port
SP Ctrl (SPCR)
Rcv Ctrl (RCR)
21 20 17 5 4 1
Xmt Ctrl (XCR)
Rate (SRGR)
XINTM XRDY RINTM RRDY
Pin Ctrl (PCR) RW R RW R
The EDMA, on the other hand, only receives data ready events (REVT, XEVT).
The EDMA events and CPU interrupts can work hand-in-hand, though. Normal data ready events can be serviced by
the EDMA, while CPU can be interrupted to handle error conditions that might occur.
The above channels with shown with their sync events was originally designed for the C6711.
The C6713, though, has many more peripherals and thus additional synchronization events. To
allow the 16 channel EDMA to accommodate a much larger number of event sources, you can
now configure the EDMA channels with whichever event source you prefer. This is done through
the memory-mapped EDMA event selector registers. Please refer to the C6713 data sheet
additional information.
The list above is the default values for the C6713 EDMA channels. Since the events we care
about in our lab exercises are on the above list, we won’t have to reconfigure the EDMA’s event
sources.
The C6416 also has a vast number of EDMA event sources. With 64 channels, though, there are
still more channels than there are sources. The next page shows the C6416 events and their
associated channels.
Included below is a page from the C6416 datasheet which lists the EDMA channel sync events.
Since an event source is going to send a signal whether you want the EDMA to respond or not,
the EER allows you to prevent the associated channel from running.
EDMA_setChannel(hMyChan) 1 EER... = 1
...
XEVT1 0 14
EER14 = 1 XEVT1
REVT1 0 15
EER15 = 0 REVT1
Hint: When you set an ER bit from the CPU (for example, when using the
EDMA_setChannel() function as we have been doing in our past two lab exercises), the
associated EER bit value is ignored. That is, manually setting a channel to run will occur
regardless of the value in EER.
AIC23 Codec
Control
Channel
Data
Channel
(Left, Right)
The DSK utilizes two McBSP’s to handle AIC23 setup and data transfers, respectively. While one McBSP
could be used to handle a single AIC23, it was easier (and saved a small amount of ‘glue’ logic) to use two
McBSP’s. Besides, the DSK has only one codec and the DSP’s have 2 or 3 McBSP’s.
McBSP1
Control
McBSP2
Data
The C6416 DSK was designed first. It utilized McBSP1 and McBSP2 for the codec interface.
When the C6713 DSK was designed, though, McBSP0 & McBSP1 had to be used since the
C6713 doesn’t have a McBSP2.
McBSP0
Control
McBSP1
Data
To initialize our data stream, we first initialize the McBSP, then use it to setup the codec.
T TO
Technical Training
Organization
McBSP Init
The McBSP’s can be initialized use CSL functions, definitions, and macros. The process is
similar to that of setting up the EDMA. Though, you’ll find the McBSP has more choices and
registers. (Good in that all these options belie its flexibility; less so in that you have to figure
them all out.)
One thing that differs between EDMA configuration and McBSP configuration is that the McBSP
configuration choices are directly related to what the port is connected to. On the DSK, this is the
AIC23 codec.
With the great flexibility of the McBSP, you can connect to a great many types of serial devices.
In each case, though, you will need to read and understand the data sheet of the device you are
connecting to and configure the McBSP accordingly. (This isn’t unlike the old days of using
computer modems. To connect to your bank, for example, you usually needed to know the proper
settings: bit size, parity, etc.)
The process of reading and deciphering a codec datasheet can be time consuming (and sometimes
difficult). Based on this, and the fact that all serial devices seem to work differently, we have
chosen not to spend the hours required for this process. Rather, we have provided the McBSP
settings provided by the DSK board manufacturer.
The McBSP settings provided by the DSK designers are used in the provided MCBSP_Config
structures. Still, you will get to write the remaining McBSP initialization code. Shown below are
the same six CSL steps we have been using to configure other peripherals.
1. McBSP Setup
1 #include <csl.h>
#include <csl_mcbsp.h>
2 MCBSP_Handle hMcbsp0;
3 MCBSP_Config mcbspCfgControl = {
0x00001000, // Serial Port Control Reg. (SPCR)
0x00000000, // Receiver Control Reg. (RCR)
0x00000040, // Transmitter Control Reg. (XCR)
0x20001363, // Sample-Rate Generator Reg. (SRGR)
0x00000000, // Multichannel Control Reg. (MCR)
0x00000000, // Receiver Channel Enable (RCER)
0x00000000, // Transmitter Channel Enable (XCER)
0x00000A0A // Pin Control Reg. (PCR)
};
void initMcBSP()
{
4 hMcbsp0 = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);
MCBSP_config(hMcbsp0, &mcbspCfgControl );
5
MCBSP_start (hMcbsp0, MCBSP_XMIT_START |
6 MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC, 100);
}
T TO
Technical Training
Organization
While your instructor won’t show the remaining three slides of the McBSP configuration, they
are provided for completeness.
T TO
Technical Training
Organization
These
These registers
registerscontrol
control the
the multi-channel
multi-channel
capabilities
capabilities of
of the
theMcBSP.
McBSP.
We
Wearen’t
aren’t using
usingthese
these features
featuresin
in our
ourlab
lab
exercises.
exercises.
T TO
Technical Training
Organization
T TO
Technical Training
Organization
Codec Initialization
Control McBSP AIC23
SPCR SRGR Codec
1. Setup McBSP RCR PCR
XCR MCR
The codec contains a number of control registers that need to be programmed. These registers
specify options for: input and output gain, codec loopback mode, sample frequency, bit-
resolution, etc.
Again, since a codec init routine is specific to a given codec, we have provided this routine for
you. From the diagram above, you can see the codec routine includes an initialization structure,
and a routine that sends the values via the McBSP to the codec control registers. You will find
this code in the codec.c file.
Of course, the upcoming lab uses the EDMA to perform the codec reads and writes. This is
common for most systems, and a good suggestion, since the EDMA can easily off-load this task
from the CPU.
Note: Not only do you save the CPU MIPs required to the do the reads/writes, but you also
minimize the cycles required by the CPU interrupt overhead.
When using the EDMA for McBSP reads/writes, there are a few changes that need to be made to
our previous EDMA initialization code. Here’s an example of using the EDMA channel for
McBSP transmit:
Lab 6
Lab 6 – Audio Pass Thru
McBSP EDMA CPU
Rcv gBufRcv
+
ADC RCVCHAN
Xmt COPY
gBufXmt
DAC XMTCHAN
Goals:
1. EDMA (RCV) copies values from DRR to gBufRcv
2. CPU copies gBufRcv to gBufXmt
3. EDMA (XMT) copies gBufXmt to DXR
4. Opt: add sine to gBufRcv based on DIP switch
T TO
Technical Training
Organization
In order to successfully complete this lab, we will need to make the following changes to our
code:
1. Change the buffer names so that they make more sense for an audio pass-through. We used
names that imply whether the buffer is being used for receive or transmit of the audio.
2. Write the code to initialize two McBSP's (one for control, and one for data).
3. Call a provided routine to initialize the AIC23 codec.
4. Change the transmit EDMA's setup to talk to the McBSP.
5. Add a receive EDMA channel to talk to the McBSP.
6. Modify the EDMA HWI that we have been using to respond to both transmit and receive
interrupts, and copy the data.
We have provided some paper exercises to help you along the way. Please use the exercises to
test your understanding of what you are doing in this lab. If you have any questions, please feel
free to ask your instructor.
As we discussed, the DSK uses two McBSP's to interface with the codec:
• One serial port to setup and configure the codec.
A global variable, called mcbspCfgControl, was created and initialized with the appropriate
bitfield values to send control register values to the AIC23.
• A second serial port to send and receive data to/from the codec.
The global variable mcbspCfgData contains the configuration values to setup the serial port
which reads/writes data to the AIC23.
When you want to use your modem to connect to your bank, first you must get the configuration
choices from them (e.g. 9600 baud, 8-bits, no-parity, etc.). Once you have this information, you
can configure the modem.
In the same fashion, once you know the configuration options required by the serial device you
are connecting the McBSP to, you can easily plug them in. Unfortunately, extracting the required
information from an analogue data converter datasheet is often not trivial. Ideally, we would have
enjoyed taking you through this process for the AIC23, but given the time constraints in the
workshop plus the fact that you most likely are using another converter (or if using the AIC23,
you can just use our code) we decided to provide these Config’s for you.
To make this all a little easier, we have provided a space for you to write your answers on paper,
before you try to write the code. You will need to refer back to the lecture material to figure out
exactly what to write. We have provided some hints to help you. These hints are the actual lab
steps that you will do to write the code inside CCS. Please write this code in the space provided
on the next page …
mcbsp.c
// ======== Include files ========
MCBSP_Config mcbspCfgData = {
Provided for you. See file for details.
};
// McBSP Handles
Hint: MCBSP_ hMcbspControl;
Control Data
6713 DSK McBSP0 McBSP1
6416 DSK McBSP1 McBSP2
MCBSP_start(hMcbspControl, MCBSP_XMIT_START |
MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC, 100);
Note: This is all one line of code. Since it is so long we broke it up for you. The value 100 is the
sample rate generator delay. McBSP logic requires 2 SRGR clock cycles after enabling
the sample rate generator for its logic to stabilize. This parameter is used to provide the
appropriate delay.
if (MCBSP_rrdy(hMcbspData))
MCBSP_read(hMcbspData);
This code checks to see if there is anything in the register. If there is, it reads it and throws it
away.
17. Start the data serial port
We are using different pieces of the data serial port, so the code to start it is a little different:
To make sure that we understand the changes that we are making, let's do another paper exercise
before we write the code. Take a look at the following sheet and try to figure out what changes
will need to be made in order to configure the EDMA to exchange data with the McBSP, for both
receive and transmit.
edma.c
EDMA_Config gEdmaConfig = {
EDMA_OPT_RMK(
EDMA_OPT_PRI_LOW, // Priority
EDMA_OPT_ESIZE_16BIT, // Element size
EDMA_OPT_2DS_NO, // 2 dimensional source
EDMA_OPT_SUM_INC, // Src update mode
EDMA_OPT_2DD_NO, // 2 dimensional dest
EDMA_OPT_DUM_INC, // Dest update mode
EDMA_OPT_TCINT_YES, // Cause EDMA interrupt
Hint: EDMA_OPT_TCC_OF(0), // Transfer Complete Code
Step 24 EDMA_OPT_TCCM_DEFAULT, // TCC Upper Bits (c64x only)
EDMA_OPT_ATCINT_DEFAULT, // Alternate TCC Interrupt (c64x only)
EDMA_OPT_ATCC_DEFAULT, // Alternate TCC (c64x only)
EDMA_OPT_PDTS_DEFAULT, // PDT Source (c64x only)
EDMA_OPT_PDTD_DEFAULT, // PDT Dest (c64x only)
EDMA_OPT_LINK_NO, // Enable link parameters
EDMA_OPT_FS_YES // Use frame sync
),
EDMA_SRC_OF(gBuf0), // src address
EDMA_CNT_OF(BUFFSIZE), // Count = buffer size
EDMA_DST_OF(gBuf1), // dest address
EDMA_IDX_OF(0), // frame/element index value
EDMA_RLD_OF(0) // reload
}; gEdmaConfigXmt
already exists, copy
EDMA_Config gEdmaConfigXmt = { it to create
EDMA_OPT_RMK( gEdmaConfigRcv
EDMA_OPT_PRI_LOW, // Priority
EDMA_OPT_ESIZE_16BIT, // Element size
EDMA_OPT_2DS_NO, // 2 dimensional source
EDMA_OPT_SUM_INC, // Src update mode
EDMA_OPT_2DD_NO, // 2 dimensional dest
EDMA_OPT_DUM_INC, // Dest update mode
EDMA_OPT_TCINT_YES, // Cause EDMA interrupt
Hint: EDMA_OPT_TCC_OF(0), // Transfer Complete Code
EDMA_OPT_TCCM_DEFAULT, // TCC Upper Bits (c64x only)
Step 23
EDMA_OPT_ATCINT_DEFAULT, // Alternate TCC Interrupt (c64x only)
EDMA_OPT_ATCC_DEFAULT, // Alternate TCC (c64x only)
EDMA_OPT_PDTS_DEFAULT, // PDT Source (c64x only)
EDMA_OPT_PDTD_DEFAULT, // PDT Dest (c64x only)
EDMA_OPT_LINK_NO, // Enable link parameters
EDMA_OPT_FS_YES // Use frame sync
),
EDMA_SRC_OF(gBuf0), // src address
EDMA_CNT_OF(BUFFSIZE), // Count = buffer size
EDMA_DST_OF(gBuf1), // dest address
EDMA_IDX_OF(0), // frame/element index value
EDMA_RLD_OF(0) // reload
};
Note: Refer to the lab diagram and draw notes on that diagram to help you gain a mental image
of what is going on in the lab. This will help drive a better understanding of the necessary
steps to get the lab working.
Instructions
Here is another exercise to help you understand the changes that you need to make to your code.
The opposite page is basically a picture of what your initEdma( ) function will look like if you
take the code that we have already written for Lab 5 and modify it to create a Receive channel
and communicate with the McBSP. We've already copied the code to create the Receive EDMA
channel for you, like we did with the structures earlier. But, we haven't made all of the changes
the you will need to make. We did change the comments for you if you need some help.
So, take a few minutes and try to make all of the necessary changes to the code. We've already
made a few of them for you so that you have an idea of what we are looking for. If you need
some help, use the hints provided to refer to the actual lab steps that will help you write the code
in CCS.
Step 27
// configure the transmit channel with the correct structure
EDMA_config(hEdmaXmt, &gEdmaConfigXmt);
Note: The EDMA_enableChannel() API enables the specified channel using the channel's
handle obtained through the _open API. It does not tell the channel to start transferring.
In this lab, we accomplish that by using a sync event.
Note: We need to make sure BOTH interrupts occur. If only one has triggered, the ISR does
nothing but return to the while loop and wait for the 2nd one to trigger.
Source Files
main.c edma.c mcbsp.c
<csl.h> <csl.h> <csl.h>
<csl_edma.h> <csl_edma.h> <csl_mcbsp.h>
"sine.h" "codec.h"
Header
<csl_irq.h> "mcbsp.h"
Files
"sine.h"
"edma.h"
"mcbsp.h"
Don't forget that ordering is also important with header files. For example, csl.h needs to be
included before any files that are dependent on it, csl_edma.h, csl_mcbsp.h, or anything else
starting with csl_*.h.
41. Build the project and load it to the DSK
42. Run the code
You should hear audio playing from your speakers or headphones. If there is any distortion,
adjust the volume level on your PC. If you get noise, go back and debug your code. Follow
the data from the input/receive side to the output/transmit side. If your audio doesn’t sound
good, try to find the error. If, after 5 minutes, you’re stuck, compare the solution to your code
and fix the error. Sometimes copying in the mcbsp configuration from the solution helps.If
you get frustrated, ask your instructor for help.
43. Halt the processor
Part A
Note: If you had troubles getting Lab 6 to work, copy the files from \solutions\lab6 and begin
working on the next step shown below.
Note: We used a lower sampling rate in the earlier labs so that the graphs would look better.
Otherwise, you would not see a full cycle of the sine wave.
You’re done
Optional Topics
DMA vs EDMA: Event Synchronization
16-bit Pixels DMA Synchronization
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18 DMA D/A
19 20 21 22 23 24
25 26 27 28 29 30 EXT_INT4 “Next”
31 32 33 34 35 36
(Src: mem_8) Is the DAC as fast as the EDMA?
No, the EDMA needs to be sync’d up to the DAC.
Unlike the EDMA, any DMA channel can be sync’d
to and EDMA event.
DMA Sync Events
00000 None (default)
00001 TINT0
00010 TINT1
DMA 00100 EXT_INT4
Primary Ctrl ... (see periph guide)
Secondary Ctrl
Source 23 19 13 9 8 7 6 5 4 1 0
Destination WSYNC RSYNC INDEX ESIZE DSTDIR
DSTDIR SRCDIR START
00100 00
Xfr Count
T TO
Technical Training
Organization
Frame Synchronization
FS
FS (Frame
(Frame Sync)
Sync)
0:
0: NO
NO (no
(no Frame
Frame Sync)
Sync)
1:
1: YES
YES (use
(use Frame
Frame Sync)
Sync)
Move
Move whole
whole frame
frame on
on
sync event
sync event
26 23 19 18 14 1 0
FS WSYNC RSYNC START
T TO
Technical Training
Organization
4 addresses are needed when handling receive & transmit parts of a serial port,
unfortunately the DMA only has two address registers. This is solved by:
1. Select SPLIT mode in Primary Control Register
2. Source/Destination registers contain the From/To memory addresses
3. Use global reg (A, B, or C) for address of McBSP’s DRR register.
DMA split mode knows to find the DXR address in the next word location.
11 10
DMA SPLIT
Primary Ctrl 01
Secondary Ctrl
Split Mode: 00 Split Disabled
Source
01 Use Global Address Reg A
Destination
10 Use Global Address Reg B
T TO Xfr Count 11 Use Global Address Reg C
Technical Training
Organization
element element
Sync frame frame
2D (block)
Any channel
Sync Events Each channel has specific event
can use any event
CPU Interrupts 4 1
Interrupt six: 3 for Count
Count = 0
Conditions 3 for errors
Reload (Auto-Init) ~2 69 21