Hi,
I've written a McBSP uart program on TMS320VC5402.
I referenced the pdf TMS320C620x/C642x McBSP: UART(spra633c.pdf), and I doesn't use DMA.
I tested my code by connecting PC. McBSP sending data is correct. But McBSP receiving data from PC is not correct.
Here is my code:
/* Include files */
#include <stdio.h>
#include <csl.h>
#include <csl_mcbsp.h>
#include <csl_irq.h>
/* Create buffers and aligning them on an L2 cache line boundary. */
#pragma DATA_SECTION(xmitbuf,"xmit_buf");
unsigned short xmitbuf[0x0400];
#pragma DATA_SECTION(recvbuf,"recv_buf");
unsigned short recvbuf[0x0400];
/* Declare CSL objects */
MCBSP_Handle hMcbsp1; /* handle for McBSP1 */
#define BUFFER_SIZE 27 /* total number of UART data words */
/* Global Variables */
char xmit_msg[BUFFER_SIZE] = "McBSP does UART on C5000!\n";
char recv_msg[BUFFER_SIZE] = "Transmission didn't work!\n";
/* Get referenc to start of interrupt vector table */
/* This symbol is defined in file, vectors.s54 */
extern void VECSTART(void);
/* Prototypes */
void ConfigMcBSP(void);
void ProcessTransmitData();
void ProcessReceiveData();
int CheckTestCase(void);
short VoteLogic(unsigned short value);
/* Create a MCBSP configuration structure */
static MCBSP_Config ConfigMcBspUart= {
/* SPCR Setup */
MCBSP_SPCR1_RMK(
MCBSP_SPCR1_DLB_OFF, /* DLB */
MCBSP_SPCR1_RJUST_RZF, /* RJUST */
MCBSP_SPCR1_CLKSTP_DISABLE, /* CLKSTP */
MCBSP_SPCR1_DXENA_NA, /* DXENA */
MCBSP_SPCR1_RINTM_RRDY, /* RINTM */
MCBSP_SPCR1_RRST_DEFAULT /* RRST */
),
MCBSP_SPCR2_RMK(
MCBSP_SPCR2_FREE_NO, /* FREE */
MCBSP_SPCR2_SOFT_NO, /* SOFT */
MCBSP_SPCR2_FRST_DEFAULT, /* FRST */
MCBSP_SPCR2_GRST_DEFAULT, /* GRST */
MCBSP_SPCR2_XINTM_XRDY, /* XINTM */
MCBSP_SPCR2_XRST_DEFAULT /* XRST */
),
/* RCR Setup */
MCBSP_RCR1_RMK(
MCBSP_RCR1_RFRLEN1_OF(8), /* RFRLEN1 */
MCBSP_RCR1_RWDLEN1_16BIT /* RWDLEN1 */
),
MCBSP_RCR2_RMK(
MCBSP_RCR2_RPHASE_DUAL, /* RPHASE */
MCBSP_RCR2_RFRLEN2_OF(1), /* RFRLEN2 */
MCBSP_RCR2_RWDLEN2_8BIT, /* RWDLEN2 */
MCBSP_RCR2_RCOMPAND_MSB, /* RCOMPAND */
MCBSP_RCR2_RFIG_NO, /* RFIG */
MCBSP_RCR2_RDATDLY_1BIT /* RDATDLY */
),
/* XCR */
MCBSP_XCR1_RMK(
MCBSP_XCR1_XFRLEN1_OF(8), /* XFRLEN1 */
MCBSP_XCR1_XWDLEN1_16BIT /* XWDLEN1 */
),
MCBSP_XCR2_RMK(
MCBSP_XCR2_XPHASE_DUAL, /* XPHASE */
MCBSP_XCR2_XFRLEN2_OF(1), /* XFRLEN2 */
MCBSP_XCR2_XWDLEN2_8BIT, /* XWDLEN2 */
MCBSP_XCR2_XCOMPAND_MSB, /* XCOMPAND */
MCBSP_XCR2_XFIG_YES, /* XFIG */
MCBSP_XCR2_XDATDLY_0BIT /* XDATDLY */
),
/* SRGR */
MCBSP_SRGR1_RMK(
MCBSP_SRGR1_FWID_DEFAULT, /* FWID */
MCBSP_SRGR1_CLKGDV_OF(56) /* CLKGDV */
),
MCBSP_SRGR2_RMK(
MCBSP_SRGR2_GSYNC_FREE, /* FREE */
MCBSP_SRGR2_CLKSP_RISING, /* CLKSP */
MCBSP_SRGR2_CLKSM_INTERNAL, /* CLKSM */
MCBSP_SRGR2_FSGM_DXR2XSR, /* FSGM */
MCBSP_SRGR2_FPER_DEFAULT /* FPER */
),
/* MCR */
MCBSP_MCR1_DEFAULT,
MCBSP_MCR2_DEFAULT,
/* PCR */
MCBSP_PCR_RMK(
MCBSP_PCR_XIOEN_SP, /* XIOEN */
MCBSP_PCR_RIOEN_SP, /* RIOEN */
1, /* FSXM = 1 */
0, /* FSRM = 0 */
1, /* CLKXM = 1 */
1, /* CLKRM = 1 */
1, /* FSXP = 1 */
1, /* FSRP = 1 */
MCBSP_PCR_CLKXP_RISING, /* CLKXP */
MCBSP_PCR_CLKRP_FALLING /* CLKRP */
),
MCBSP_RCERA_DEFAULT,
MCBSP_RCERB_DEFAULT,
MCBSP_XCERA_DEFAULT,
MCBSP_XCERB_DEFAULT,
};
/*******************************************************************/
/* void main(void) */
/*******************************************************************/
void main(void)
{
// int waittime = 0;
// int works = FALSE;
unsigned short * xmitbufptr;
unsigned short * recvbufptr;
unsigned short val;
unsigned short * ptr;
int i;
/* initialize the CSL library */
CSL_init();
/* Set IPTR to start of interrupt vector table */
IRQ_setVecs((Uint16)(&VECSTART));
/* process transmit data */
printf("Processing Transmit string...\n");
ProcessTransmitData();
printf("String transmitted: %s \n", xmit_msg);
/* Open the McBSP channel 1 */
hMcbsp1 = MCBSP_open(MCBSP_PORT1, MCBSP_OPEN_RESET);
/* Setup for McBSP */
ConfigMcBSP();
/* Start the MCBSP and Sample Rate Generator */
MCBSP_start(hMcbsp1,
MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC |
MCBSP_RCV_START | MCBSP_XMIT_START,
0x200
);
// send data for test
/* point to Transmit Buffer */
xmitbufptr = (unsigned short *)xmitbuf;
for( i = 0; i< BUFFER_SIZE * 11; i++ )
{
while (!MCBSP_xrdy(hMcbsp1));
MCBSP_write16(hMcbsp1,xmitbufptr[i]);
//printf("====write 16bit : %d\n",xmitbufptr[i]);
}
// receive test data
recvbufptr = (unsigned short *) recvbuf;
for( i = 0; i< (BUFFER_SIZE * 11); i++ )
{
/* Wait for RRDY signal to read data from DRR */
while (!MCBSP_rrdy(hMcbsp1));
/* Read 16 bit value from DRR */
recvbufptr[i] = MCBSP_read16(hMcbsp1);
}
/* process received data */
printf("Processing Receive string...\n");
ProcessReceiveData();
printf("String received: %s \n", recv_msg);
MCBSP_close(hMcbsp1); /* close McBSP 1 */
printf("============ completed =============\n");
} /* End of main() */
/*******************************************************************/
/* void ConfigMcBSP(void): Setup for McBSP Configuration */
/*******************************************************************/
void ConfigMcBSP(void)
{
MCBSP_config(hMcbsp1, &ConfigMcBspUart);
} /* end of Config_McBSP(void) */
/*******************************************************************/
/* void ProcessTransmitData(void) */
/* */
/* This function expands each of the 8-bit ASCII characters in the */
/* transmit string "xmit_msg" into UART transmission 16-bit word */
/* and place them in the transmit buffer "xmitbuf". In addition, */
/* 16-bit Start and 8-bit Stop framing words, respectively, are */
/* inserted before and after each of the ASCII characters in the */
/* buffer. */
/*******************************************************************/
void ProcessTransmitData(void)
{
int i;
short cnt = 1;
unsigned char xmit_char;
unsigned short *xmitbufptr;
/* point to Transmit Buffer */
xmitbufptr = (unsigned short *)xmitbuf;
for (i=0; i<(sizeof(xmitbuf)/sizeof(unsigned int)); i++)
{
xmitbufptr[i] = 0x0000; /* zero fill buffer */
}
xmitbufptr = (unsigned short *)xmitbuf;
/* Process data BYTES in xmit_msg[] and put in xmit buffer */
for (i = 0; i < BUFFER_SIZE; i++)
{
/*Get transmit character (one byte) from xmit_msg[] and put in xmit buffer*/
xmit_char = xmit_msg[i];
/* Process each BYTE of transmit character */
for (cnt = -1; cnt < 10; cnt++)
{
if (cnt == -1)
*xmitbufptr++ = 0x0000;
else if (cnt == 8 || cnt ==9)
*xmitbufptr++ = 0xFFFF;
else if (xmit_char & (1 << cnt))
*xmitbufptr++ = 0xFFFF;
else
*xmitbufptr++ = 0x0000;
} /* end for cnt */
} /* end for i */
} /* end ProcessTransmitData */
/*******************************************************************/
/* void ProcessReceiveData(void) */
/* */
/* This function decodes the data in the receive buffer, "recvbuf" */
/* and strips the framing start (0x0000) and Stop (0xFFFF) words. */
/* It calls the subroutine VoteLogic() to determine each bit of */
/* the ASCII character. It then puts the result in recv_msg. */
/*******************************************************************/
void ProcessReceiveData(void)
{
int i;
unsigned char recv_char = 0;
short cnt = -1;
short recv_val;
unsigned short raw_data;
unsigned short *recvbufptr; /*receive buffer pointer*/
/* Point to the receive buffer */
recvbufptr = (unsigned short *)recvbuf;
/* Process all data in the Receive buffer */
for (i = 0; i < BUFFER_SIZE; i++)
{
recv_char = 0;
/* Process each UART frame */
for (cnt = -1; cnt < 10; cnt++)
{
if(cnt == -1 || cnt == 8 || cnt == 9)
{
/* Ignore Start and Stop bits */
*recvbufptr++;
}
else
{
/* Get 16-bit data from receive buffer */
raw_data = *recvbufptr;
recvbufptr++;
/* get the value of the majority of the bits */
recv_val = VoteLogic(raw_data);
/* put received bit into proper place */
recv_char += recv_val << cnt;
}
} /* end for cnt */
/* A full BYTE is decoded. Put in result: recv_msg[i] */
recv_msg[i] = recv_char;
} /* end for i */
} /* end ProcessReceiveData() function */
/*******************************************************************/
/* void CheckTestCase(void) */
/*******************************************************************/
int CheckTestCase(void)
{
unsigned short *source;
unsigned short *result;
unsigned int i = 0;
short cnt = -1;
int error = 0;
source = (unsigned short *) xmitbuf;
result = (unsigned short *) recvbuf;
for (i = 0; i < BUFFER_SIZE ; i++)
{
for (cnt = -1; cnt < 10; cnt++)
{
/* Ignore the start and stop bits */
if(cnt == -1 || cnt == 8 || cnt ==9)
{
source++;
result++;
}
else
{
if (*source != *result)
{
error = i + 1;
break;
}
source++;
result++;
}
}
}
return(error);
} /* end CheckTestCase() function */
/*******************************************************************/
/* short VoteLogic(unsigned short) */
/* */
/* This function decoded the received character by testing the */
/* center 4 bits of the baud. A majority rule is used for the */
/* decoding. */
/*******************************************************************/
short VoteLogic(unsigned short value)
{
short returnvalue;
switch ((value >> 6) & 0x0F)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 8:
case 9:
case 10:
returnvalue = 0;
break;
case 7:
case 11:
case 12:
case 13:
case 14:
case 15:
returnvalue = 1 ;
break;
} /* end switch */
return (returnvalue);
} /* end VoteLogic() funciton */
Can anyone tell me what's my problem or give me a sample code ( receive data without DMA ), thanks