Hi all,
I am using C6713DSK to interface with a 2-channel ADC ADS7945EVM, through McBSP0 in SPI mode. However, I have encountered problem in switching between the 2 ADC channels. According to the ADS7945EVM user's guide and datasheet, the McBSP as the SPI master need to send 0x0000 or 0xFFFF to the ADC to select channel 0 or 1 respectively. I have come up with an interrupt service routine for RRDY to read from the 1st channel and then toggle the channel selection to read from the 2nd channel for the next interrupt, but when I monitor the MOSI pin on oscilloscope, the channel selection signal is not toggling consistently for every frame sync, most of the time it takes 2 frame sync to toggle. I'm wondering if it is that my ISR has exceeded the interval between 2 interrupt call, but apparently the total instruction cycle of my ISR can't be that long. Here is my code including the McBSP setting, main function and the ISR for RRDY, the program is built by DSP bios. Is it that the way that I am toggling the channel selection signal is wrong, or there are more efficient ways of doing it?
#include "mcbsp_interruptcfg.h"
#include <stdio.h>
#include <math.h>
#include <csl.h>
#include <csl_mcbsp.h>
#include "dsk6713.h"
#include "dsk6713_dip.h"
#include "DAC_input.c"
/* create a config structure */
static MCBSP_Config ConfigLoopback = {
/* Serial Port Control Register (SPCR) */
MCBSP_SPCR_RMK(
MCBSP_SPCR_FREE_YES,
MCBSP_SPCR_SOFT_YES,
MCBSP_SPCR_FRST_YES,
MCBSP_SPCR_GRST_YES,
MCBSP_SPCR_XINTM_XRDY,
MCBSP_SPCR_XSYNCERR_NO,
MCBSP_SPCR_XRST_YES,
MCBSP_SPCR_DLB_OFF,
MCBSP_SPCR_RJUST_RZF,
MCBSP_SPCR_CLKSTP_DELAY,
MCBSP_SPCR_DXENA_OFF,
MCBSP_SPCR_RINTM_RRDY,
MCBSP_SPCR_RSYNCERR_NO,
MCBSP_SPCR_RRST_YES ),
/* Receive Control Register (RCR) */
MCBSP_RCR_RMK(
MCBSP_RCR_RPHASE_SINGLE,
MCBSP_RCR_RFRLEN2_OF(0),
MCBSP_RCR_RWDLEN2_8BIT,
MCBSP_RCR_RCOMPAND_MSB,
MCBSP_RCR_RFIG_YES,
MCBSP_RCR_RDATDLY_1BIT,
MCBSP_RCR_RFRLEN1_OF(0),
MCBSP_RCR_RWDLEN1_16BIT, // Receive element length in phase 1(RWDLEN1) (16 bit)
MCBSP_RCR_RWDREVRS_DISABLE/ ),
/* Transmit Control Register (XCR) */
MCBSP_XCR_RMK(
MCBSP_XCR_XPHASE_SINGLE,
MCBSP_XCR_XFRLEN2_OF(0),
MCBSP_XCR_XWDLEN2_8BIT,
MCBSP_XCR_XCOMPAND_MSB,
MCBSP_XCR_XFIG_YES,
MCBSP_XCR_XDATDLY_1BIT,
MCBSP_XCR_XFRLEN1_OF(0),
MCBSP_XCR_XWDLEN1_16BIT, // Transmit element length in phase 1(XWDLEN1) (16 bit)
MCBSP_XCR_XWDREVRS_DISABLE ),
/*serial port sample rate generator register(SRGR) */
MCBSP_SRGR_RMK(
MCBSP_SRGR_GSYNC_FREE,
MCBSP_SRGR_CLKSP_RISING,
MCBSP_SRGR_CLKSM_INTERNAL,
MCBSP_SRGR_FSGM_FSG,
MCBSP_SRGR_FPER_OF(18), // Frame period(FPER)
(19 bit clock)
MCBSP_SRGR_FWID_OF(0), // Frame width(FWID)
(1 bit clock)
MCBSP_SRGR_CLKGDV_OF(2) // Sample rate generator clock divider(CLKGDV) (37.5 MHz)
),
MCBSP_MCR_DEFAULT, /* Using default value of MCR register */
MCBSP_RCER_DEFAULT,/* Using default value of RCER register */
MCBSP_XCER_DEFAULT,/* Using default value of XCER register */
/* serial port pin control register(PCR) */
MCBSP_PCR_RMK(
MCBSP_PCR_XIOEN_SP,
MCBSP_PCR_RIOEN_SP,
MCBSP_PCR_FSXM_INTERNAL,
MCBSP_PCR_FSRM_EXTERNAL,
MCBSP_PCR_CLKXM_OUTPUT,
MCBSP_PCR_CLKRM_INPUT,
MCBSP_PCR_CLKSSTAT_0,
MCBSP_PCR_DXSTAT_0,
MCBSP_PCR_FSXP_ACTIVELOW,
MCBSP_PCR_FSRP_ACTIVEHIGH,
MCBSP_PCR_CLKXP_RISING,
MCBSP_PCR_CLKRP_FALLING )
};
/* Global parameters */
MCBSP_Handle hMcbsp;
Uint16 x_buf[500]; // buffer for channel 0
Uint16 x_buf1[500]; // buffer for channel 1
Uint16 n=0;
char signal=0; // variable used for channel selection
/* Function Prototype */
void rintHWI (void);
/* ---------------------------------------------------------------------------*/
void main() {
/* Initialize CSL and BSL */
DSK6713_init();
DSK6713_DIP_init();
CSL_init();
/* set MCBSP0 and MCBSP1 off board */
DSK6713_rset(DSK6713_MISC,0x03);
/* Open up serial port 0 */
hMcbsp = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);
/* Sets up McBSP port 0 */
MCBSP_config(hMcbsp,&ConfigLoopback);
/* Starts McBSP0 */
MCBSP_start(hMcbsp, MCBSP_RCV_START | MCBSP_XMIT_START |
MCBSP_SRGR_START| MCBSP_SRGR_FRAMESYNC, 0x00001000);
/* Interrupt setup */
IRQ_globalDisable(); // globally disable interrupt
IRQ_enable(IRQ_EVT_RINT0); // enable receiver0 interrupt event
IRQ_globalEnable(); // globally enable interrupt
/* wait until the transmitter is ready for a sample then write to it */
while (!MCBSP_xrdy(hMcbsp));
MCBSP_write(hMcbsp,0x00000000); // select channel 0 in the 1st read
}
/* Interrupt routine when rrdy is set */
void rintHWI (void)
{
if (signal == 0) // read from channel 0
{
x_buf[n] = MCBSP_read(hMcbsp); // read and save in the 1st buffer
MCBSP_write(hMcbsp,0x0000FFFF); // read from channel 1 in the next interrupt call
signal = 1; // toggle the channel selection
DSK6713_wait(1);
}
else // read from channel 1
{
x_buf1[n] = MCBSP_read(hMcbsp); // read and save in the 2nd buffer
MCBSP_write(hMcbsp,0x00000000); // read from channel 0 in the next interrupt call
signal = 1; // toggle the channel selection
DSK6713_wait(1);
n++;
if (n>499)
n=0;
}
}
Furthermore, if I change the transmit frame sync signal generation to DXR-to-XSR copy, no frame sync signal is observed at the oscilloscope. Can anyone tell me why is this happening? Your help is highly appreciated, cheers
Neo