Skip to content Skip to navigation

Connexions

You are here: Home » Content » A/D, D/A, and Sampling

Navigation

Recently Viewed

This feature requires Javascript to be enabled.
 

A/D, D/A, and Sampling

Module by: Hyeokho Choi. E-mail the author

Summary: This will acquaint you with the peripheral setup on the C6211 DSK board for A/D and D/A conversion.

Lab Objective

This lab is to acquaint you with the peripheral setup on the C6211 DSK board for A/D and D/A conversion. After this lab you are expected to know how to set up McBSP1 port and the PCM3003 codec daughtercard.

Serial Port

McBPS1 Setup

The PCM3003 codec on the daughtercard is connected to the McBSP1 serial port of the C6211 CPU. Therefore, you need to set up the McBSP1 to be able to use the codec. After reset, the PCM3003 codec continuously perform A/D and D/A conversions. The configuration of the PCM3003 is changed only by hardware setting. The jumpers on the daughtercard can be set differently to change the setting. Currently, the jumpers are set for l6bit A/D and D/A at the fixed 48kHz sampling rate. The A/D conversion data are continuously dumped to the McBSP1 serial port. The D/A conversion data are continuously taken from the McBSP1 port.

To configure the McBSP1 serial port of the CPU, you need to store appropriate values to the registers controlling the serial port. These registers are memory mapped, and the physical addresses of the McBSP1 registers are


1	McBSP1_DRR	0x1900000	/* address of data receive reg.*/
2	McBSP1_DXR	0x1900004	/* address of data transmit reg.*/
3	McBSP1_SPCR	0x1900008	/* address of serial port contl. reg.*/
4	McBSP1_RCR	0xl90000C	/* address of receive control reg.*/
5	McBSP1_XCR	0x1900010	/* address of transmit control reg.*/
6	McBSP1_SRGR	0x1900014	/* address of sample rate generator */
7	McBSP1_MCR	0x1900018	/* address of multichannel reg.*/
8	McBSP1_RCER	0xl9000lC	/* address of receive channel enable.*/
9	McBSP1_XCER	0x1900020	/* address of transmit channel enable.*/
10	McBSP1_PCR	0x1900024	/* address of pin control reg.*/
          

The behavior of the McBSP1 is configured by setting up the SPCR, SRGR, PCR, RCR, and XCR registers. In the following labs, we set up the McBSP1 port so that both channels of A/D results can be read at the same time by reading a 32bit number from McBSP1. The upper and lower l6bits correspond to the left and right channels, respectively. Similarly, we set up the port output so that we can write a single 32bit number to McBSP1 for D/A conversion (again upper and lower l6bits correspond to left and right channels). For this set up, the following are the register values that need be set. Please read the McBSP registers description in the TI peripheral reference guide to understand why you should write the specified values.

  1. Write 0 to SPCR to reset McBSP1.
  2. Write 0x000C to PCR to setup the McBSP1 pins.
  3. Write 0x000000A0 to RCR to configure the receive channel as 1-phase 32 bit receive.
  4. Write 0x000000A0 to XCR to configure the transmit channel as 1-phase 32 bit transmit.
  5. Write 0 to DXR before enabling the port.
  6. Write 0x000l000l to SPCR to enable the transmit and receive.

Exercise 1: McBSP1 Setup

Write an assembly routine that sets up the McBSP1. The above registers should be set (in the given order).

Transmitting Data

The DXR register contains the data to be output from the serial port. Once you write data to DXR, they are converted to serial format and output through the serial output pin, and then the PCM3003 codec receives the data. To avoid conflicts, you should write to DXR only after the McBSP finishes the transmission of the previously written data. Then, how can you know that the McBSP finished transmission of the data in DXR and is ready to take new data to transmit? This is done by checking the bit 17 (XRDY bit) of the SPCR register. When DXR is empty and McBSP is ready to take new data, the XRDY of the SPCR register becomes 1. Therefore, you can check this flag and when SPCR is empty, you can safely write to it to transmit the new data.

Exercise 2: McBSP1 Setup

Assuming the 32-bit data to be transmitted through McBSP1 is in A0, write an assembly routine that checks the SPCR and then transmits the data to McBSP1. If DXR is not empty, your program must wait until McBSP1 finishes transmission of the remaining data.

Right after the port finishes transmitting the data, the XRDY of SPCR changes from 0 to 1 to indicate the termination of the transmission and that the port is ready to take new data. This event generates the interrupt XINT1. By enabling XINT1 and servicing this interrupt, you can avoid continuous polling of the port status.

Receive Data

The DRR register contains the data the McBSP port received from its data receive pin. After the PCM3003 codec chip finishes each A/D conversion, the result is sent to McBSP1 and stored in DRR. When the received data is available in DRR to be read by the CPU, the bit 1 (RRDY bit) of SPCR register becomes 1. Therefore, you can check this flag to see if there is any data available in DRR to be read. When the data becomes available, the serial port generates the RINT1 interrupt.

Exercise 3: Receiving Data

Write an assembly routine that checks the SPCR and then reads the data from DRR. If there is no data in DRR, your program must wait until McBSP1 receives new data into DRR.

Using MACRO and STACK

Assembler Macro

Often you need to repeat exactly the same block of code with different parameters. The assembler macro is useful in this situation. For example, you can define a macro McBSP1_write to write a register value to McBSP1. The macro is defined in the following format.


1	McBSP1_write	.macro r1
2	.....
3	;assembly code writing r1 to McBSP1
4 loop? .....
5	.....
6	B        loop?
7	.....
8	STW	 r1, *A10
9	.....
10	.....
11
12	.endm
           
Line 1 defines the name of macro and the symbolic names used inside the macro. Here r1 is the symbolic name of a register. For example, if you write.

1	McBSP1_write	Al
           
the assembler places the block of code listed in the macro with every occurrence of r1 in the macro replaced with A1. This way, you don’t have to type in the same list of code again and again. The assembler does it.

However, you need to be careful when using labels insider macro. Because macro can be called repeatedly many times in a program, the same labels will be re-defined every time the macro is called. Because multiple definition of same label is not allowed, you have to append ? at the end of each label defined inside the macro (for example, loop? in the above). With this special labels, assembler can properly assign different label names for each different call of the macro.

Exercise 4: McBSP Read and Write Macros

Write macros to write a register to McBSP1 and read from McBSP1 to a register.

Stack Implementation

When you write an assembly program, it is often useful to have some temporary storage spaces to temporarily store and restore register values, etc. The stack is often used but C62x CPU does not explicitly support the stack operations. However, you can easily define a stack.

The first thing you need to do is to allocate a memory space as a stack. This is done in the linker command file by defining a section for the stack. For example, we can have


1   MEMORY	
2   {
3    ...
4    IRAM: org = 0x00000240	len = 0x0000FCC0
5    STK:  org = 0x0000FF00	len = 0x000000FF
6    ...
7   }
8
9   SECTIONS
10  {
11   ....
12   stack :> STK
13  }
          
to define the last 256 bytes in the internal memory as the stack space. Then, in the asm program, we can allocate 256 bytes memory as stack by having

1   ...
2   SP	         .set	B15 ;use B15 as a stack pointer
3
4		 .sect	"stack"
5   endofstack:  .bes	256
6
7		 .text
8		 MVKL	endofstack—3, SP      ;initially stack is empty
9		 MVKH	endofstack-3, SP      ;and SP points to the bottom
10				              ;word boundary
11			      
12		 STW	A0, *SP—-[1]	      ;this pushes A0 to stack
13
14		 LDW	*++SP[1], AO	      ;pull the last stored stack
15				              ;data to A0
16		 NOP	5
17		 .endm
18  ...
          

Codec Setup

The operation of the PCM3003 codec can be controlled only by hardware. In all the following labs, we will use the l6bit stereo input/output at the fixed 48kHz sampling. Therefore, do not modify the jumpers on the daughtercard. Later you may modify the jumpers to obtain desired sampling rate and other operations.

Putting Things Together

Now, you have all the necessary functions to read and write the serial port for A/D and D/A conversion. In the following experiment, you write an executable program that reads sampled A/D converted data from serial port and writes to the serial port for D/A conversion.

Polling-Based Program

In the polling-based method, the program waits until the codec finishes the A/D conversion and reads the data when it’s ready. The program continuously checks the appropriate bits of the SPCR register to monitor the availability of the data.

Exercise 5: A/D, D/A Loop (Polling)

Write an assembly program that reads the A/D conversion data and directly writes back the same data for D/A conversion. By connecting an audio source and a powered speakers to the DSK board, you should be able to hear the input sound. Depending on the input signal level, it may be necessary to multiply a constant around 4 to 8 to the A/D data before D/A conversion to amplify the signal.

Interrupt-Based Program

Using interrupts, you don’t have to continuously check the data availability. By servicing the RINT1 interrupt, you can read the A/D data every time they become available. While waiting for the interrupt, the program can execute other instructions. In our case, the program simply idles waiting for interrupts.

Note:

Due to a bug of the C6211 processors on our DSK boards, RINT0/TINT0 and RINT1/TINT1 are swapped. Therefore, to enable RINT1/XINT1, you actually need to enable RINT0/XINT0.

Exercise 6: A/D, D/A Loop (Interrupt)

Write an assembly program that reads the A/D conversion data and directly writes back the same data for D/A conversion. Using the XINT1 (or RINT1) interrupt, the A/D result is read and written back for D/A conversion in the interrupt service routine. The program simply idles while waiting for interrupts. Because both A/D and D/A conversions occur at 48kHz rate, you need to service only one interrupt (use XINT1 here) to sample the signal.

Viewing and Plotting Memory Contents Using CCS

In the previous experiments, you were able to sample the input signal and listen to it through the D/A converter. Sometimes, it is often necessary to display the sampled data and analyze them using MATLAB-like software. The following experiment demonstrate how you can view and save memory contents using Code Composer.

You can define a buffer by allocating a memory space in your assembly program:


1   buffer   .space 512
        
allocates 512 bytes (256 halfwords) in the memory space.

Exercise 7: Storing Data In Buffer

Define two 512 bytes buffers, one for each channel. Name the buffers buffer_left and buffer_right. Then, add extra lines of code so that each time the CPU reads from codec, the 32 data value is split into 2 halfwords corresponding to the left and right channels. Save each channel data in the buffers starting at the top. When the buffer is full, you start overwriting the buffers from the top of the buffer again. Build the code and run. Input 10kHz sine wave to the audio codec input using the sound card tone generator. While the input is still connected, halt the CPU. The sample values remain stored in memory location where the buffer_left and buffer_right is assigned.

You can view the content of buffer memory using VIEW:MEMORY on CCS. Enter the following values to the memory view window shown in Figure 1.

Plot the buffer content using VIEW:GRAPHT:TIME/FREQUENCY on CCS. Enter the values to the graph view window as shown in Figure 2.

You can also plot the spectrum of the signal in the buffer using VIEW:GRAPHT:TIME/FREQUENCY on CCS. Change the Display Type to FFT Magnitude. The CCS will display the magnitude of the FFT of the specified data.

Exercise 8: Transfer Data To MATLAB

Save the contents of buffer as a hex file using FILE:DATA:SAVE. After entering the file name, enter the address and length of buffer as buffer_left (or buffer_right) and 512. Using the MATLAB function load_vector, read the saved hex file into MATLAB. (You can download load vector.m MATLAB script from the course web page.) Plot the signal and its spectrum and compare them with what you obtained on CCS.

Repeat the above experiment using your voice as the input source. For input, you can record a piece of your voice using the Windows voice recorder and play it through the soundcard. The soundcard output is fed to the codec input. Plot the spectrum of your voice. In which frequency range is the energy of your voice concentrated?

Figure 1
Memory View Window
Memory View Window (lab5fig1.jpg)
Figure 2
Graph Property Dialog Box
Graph Property Dialog Box (lab5fig2.jpg)

Content actions

Download module as:

PDF | EPUB (?)

What is an EPUB file?

EPUB is an electronic book format that can be read on a variety of mobile devices.

Downloading to a reading device

For detailed instructions on how to download this content's EPUB to your specific device, click the "(?)" link.

| More downloads ...

Add module to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks