Hello Everyone,
I am currently working on an application using dsk6713 for which i need uarts for serial data transmission and reception.for this i am using LR-232 uart daughter cards they also shipped demo programs with them.It works fine for serial transmission but reception part which is my real concern is confined to few bytes(means i received few bytes correct and rest of other are garbage).I made a loop back test program which receive serial data from pc(docklight application) to dsk6713 and send it back to pc again.following is my code it is interrupt based program which use HWi4 for serial interrupt and takes action as per requirement kindly guide me if there is any thing wrong in code.
#include "dsk6713_aic23.h"
#include "dsk6713_dip.h"
#include "dsk6713_led.h"
#include <stdlib.h>
#include <stdio.h>
#include "dsk6713.h"
#include <math.h>
#include <string.h>
#include <string.h>
#include "pc_demo.h"
#include <csl.h>
#include <string.h>
#define CHANNEL_TO_USE 4
#define Null 0
#define PI 3.1415926535897932384626433832795
//functions decalartion.
unsigned int UART_xmit_count(int chn);
int UART_send_block (int chn, unsigned char* buf, unsigned int length);
void initialize_UART (int chn, unsigned char divisor);
int UART_recv_block (int chn, unsigned char* buf, unsigned int length);
void delay(long value);
int UART_recv_byte (int chn, unsigned char* byte);
void ext_int(void);
unsigned int UART_recv_count(int chn);
unsigned int UART_xmit_count(int chn);
Uint32 fs = DSK6713_AIC23_FREQ_96KHZ;
unsigned char heading2[] = {" This demo program verifies the sending and receiving\015\012"};
unsigned char heading3[] = {" of data to and from the DSK. Type a number from 1-3,\015\012"};
unsigned char heading4[] = {" and the DSK will respond with the appropriate message\015\012\012"};
unsigned char menu[] = {" ---Menu---\015\012 1: Send FOX message\015\012 2: Send string of digits\015\012 3: Send Character set\015\012\012"};
unsigned char responLR-232-Tech_Ref.pdfse1[] = {" THE QUICK BROWN FOX JUMPS OVER A LAZY DOG 01234567890\015\012\012"};
unsigned char response2[] = {" 01234567890123456789012345678901234567890123456789\015\012\012"};
unsigned char response3[] = {" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\015\012\012"};
unsigned char bad_response[] = {" *** Please press 1,2 or 3 ***\015\012\012"};
void initialize_UART (int chn, unsigned char divisor)
{
switch (chn)
{
case 1:
// channel 1
UART_LCR1 = 0x80; // Set "Divisor Latch Access Bit"
UART_DLL1 = divisor; // Lower 8 bits of divisor
UART_DLM1 = 0x00; // Upper 8 bits of divisor
UART_LCR1 = 0x00; // Clear DLAB bit in Line Control Register
UART_LCR1 = 0x03; // 8 data bits, 1 stop bit, no parity
UART_IER1 = 0x01; // Enable RX int.
UART_FCR1 = 0x09; // Enable FIFO
UART_MCR1 = 0x0b; // Take Interrupt signals out of 3-state
break;
case 2:
// channel 2
UART_LCR2 = 0x80; // Set "Divisor Latch Access Bit"
UART_DLL2 = divisor; // Lower 8 bits of divisor
UART_DLM2 = 0x00; // Upper 8 bits of divisor
UART_LCR2 = 0x00; // Clear DLAB bit in Line Control Register
UART_LCR2 = 0x03; // 8 data bits, 1 stop bit, no parity
UART_IER2 = 0x01; // Enable RX int.
UART_FCR2 = 0x09; // Enable FIFO
UART_MCR2 = 0x0b; // Take Interrupt signals out of 3-state
break;
case 3:
// channel 3
UART_LCR3 = 0x80; // Set "Divisor Latch Access Bit"
UART_DLL3 = divisor; // Lower 8 bits of divisor
UART_DLM3 = 0x00; // Upper 8 bits of divisor
UART_LCR3 = 0x00; // Clear DLAB bit in Line Control Register
UART_LCR3 = 0x03; // 8 data bits, 1 stop bit, no parity
UART_IER3 = 0x01; // Enable RX int.
UART_FCR3 = 0x09; // Enable FIFO
UART_MCR3 = 0x0b; // Take Interrupt signals out of 3-state
break;
case 4:
// channel 4
UART_LCR4 = 0x80; // Set "Divisor Latch Access Bit"
UART_DLL4 = divisor; // Lower 8 bits of divisor
UART_DLM4 = 0x00; // Upper 8 bits of divisor
UART_LCR4 = 0x00; // Clear DLAB bit in Line Control Register
UART_LCR4 = 0x03; // 8 data bits, 1 stop bit, no parity
UART_IER4 = 0x01; // Enable RX int.
UART_FCR4 = 0x09; // Enable FIFO
UART_MCR4 = 0x0b; // Take Interrupt signals out of 3-state
break;
}
}
/********************************************************
The following routine reads a single character (byte)
from the UART receive buffer. If the receive buffer is
empty, -1 is returned.
********************************************************/
int UART_recv_byte (int chn, unsigned char* byte)
{
switch (chn)
{
case 1:
if (uiUART_recv_count1 == 0) return (-1);
*byte = ucUART_recv_buffer1[uiUART_recv_nextout1++];
if (uiUART_recv_nextout1 >= RECV_BUF_SIZE) uiUART_recv_nextout1=0;
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count1--;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 2:
if (uiUART_recv_count2 == 0) return (-1);
*byte = ucUART_recv_buffer2[uiUART_recv_nextout2++];
if (uiUART_recv_nextout2 >= RECV_BUF_SIZE) uiUART_recv_nextout2=0;
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count2--;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 3:
if (uiUART_recv_count3 == 0) return (-1);
*byte = ucUART_recv_buffer3[uiUART_recv_nextout3++];
if (uiUART_recv_nextout3 >= RECV_BUF_SIZE) uiUART_recv_nextout3=0;
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count3--;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 4:
if (uiUART_recv_count4 == 0) return (-1);
*byte = ucUART_recv_buffer4[uiUART_recv_nextout4++];
if (uiUART_recv_nextout4 >= RECV_BUF_SIZE) uiUART_recv_nextout4=0;
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count4--;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
}
return (0);
}
/********************************************************
The following routine first checks if there is space
in the UART transmit buffer for 'length' characters.
If there is, it places the characters (bytes) into
the buffer. If there is not enough room in the
transmit buffer, the routine returns -1, and does
not place anything in the transmit buffer.
The actual sending of the bytes to the UART will be
handled transparently by the interrupt routine when
the UART is free to accept data.
********************************************************/
int UART_send_block (int chn, unsigned char* buf, unsigned int length)
{
unsigned int index;
switch (chn)
{
case 1:
if ((uiUART_xmit_count1+length-1) >= XMIT_BUF_SIZE) return (-1);
for (index=0; index<length; index++)
{
ucUART_xmit_buffer1[uiUART_xmit_nextin1++]=buf[index];
if (uiUART_xmit_nextin1 >= XMIT_BUF_SIZE) uiUART_xmit_nextin1=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_xmit_count1 += length;
UART_IER1 = 0x03;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 2:
if ((uiUART_xmit_count2+length-1) >= XMIT_BUF_SIZE) return (-1);
for (index=0; index<length; index++)
{
ucUART_xmit_buffer2[uiUART_xmit_nextin2++]=buf[index];
if (uiUART_xmit_nextin2 >= XMIT_BUF_SIZE) uiUART_xmit_nextin2=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_xmit_count2 += length;
UART_IER2 = 0x03;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 3:
if ((uiUART_xmit_count3+length-1) >= XMIT_BUF_SIZE) return (-1);
for (index=0; index<length; index++)
{
ucUART_xmit_buffer3[uiUART_xmit_nextin3++]=buf[index];
if (uiUART_xmit_nextin3 >= XMIT_BUF_SIZE) uiUART_xmit_nextin3=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_xmit_count3 += length;
UART_IER3 = 0x03;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 4:
if ((uiUART_xmit_count4+length-1) >= XMIT_BUF_SIZE) return (-1);
for (index=0; index<length; index++)
{
ucUART_xmit_buffer4[uiUART_xmit_nextin4++]=buf[index];
if (uiUART_xmit_nextin4 >= XMIT_BUF_SIZE) uiUART_xmit_nextin4=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_xmit_count4 += length;
UART_IER4 = 0x03;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
}
return (0);
}
/********************************************************
The following routine returns the number of characters
in the receive memory buffer. Note that the interrupt
service routine (ISR) could potentially add a character to
the receive buffer immediately after this function is
called. This will not harm the integrity of the data.
Any characters placed in the receive buffer by the
ISR in this way will be picked up the next time this
function is called.
********************************************************/
unsigned int UART_recv_count(int chn)
{
switch (chn)
{
case 1:
return (uiUART_recv_count1);
case 2:
return (uiUART_recv_count2);
case 3:
return (uiUART_recv_count3);
case 4:
return (uiUART_recv_count4);
default:
return (0);
}
}
/********************************************************
The following routine returns the number of characters
in the transmit memory buffer. Note that the interrupt
service routine (ISR) could potentially remove a character from
the receive buffer immediately after this function is
called. This will not harm the integrity of the data.
********************************************************/
unsigned int UART_xmit_count(int chn)
{
switch (chn)
{
case 1:
return (uiUART_xmit_count1);
case 2:
return (uiUART_xmit_count2);
case 3:
return (uiUART_xmit_count3);
case 4:
return (uiUART_xmit_count4);
default:
return (0);
}
}
/*****************************************
The following interrupt routine is triggered by a rising edge on
External Interrupt #4. This ISR handles the UART's transmit data and
receive data interrupts for all UART channels.
*****************************************/
interrupt void c_int04()
{
unsigned char temp;
volatile unsigned char trash;
// If the uart is ready to accept a char, AND there is something
// to send, send it, and adjust the pointer and count
while(1)
{ // service channel 1 transmitter
temp = UART_LSR1;
if (((temp & 0x20) == 0x20) && uiUART_xmit_count1)
{
if(uiUART_xmit_count1 == 1) UART_IER1 = 0x01; // if last byte, disable tx int
UART_THR1 = ucUART_xmit_buffer1[uiUART_xmit_nextout1++];
if(uiUART_xmit_nextout1 >= XMIT_BUF_SIZE) uiUART_xmit_nextout1 = 0;
uiUART_xmit_count1--;
}
// service channel 2 transmitter
temp = UART_LSR2;
if (((temp & 0x20) == 0x20) && uiUART_xmit_count2)
{
if(uiUART_xmit_count2 == 1) UART_IER2 = 0x01; // if last byte, disable tx int
UART_THR2 = ucUART_xmit_buffer2[uiUART_xmit_nextout2++];
if(uiUART_xmit_nextout2 >= XMIT_BUF_SIZE) uiUART_xmit_nextout2 = 0;
uiUART_xmit_count2--;
}
// service channel 3 transmitter
temp = UART_LSR3;
if (((temp & 0x20) == 0x20) && uiUART_xmit_count3)
{
if(uiUART_xmit_count3 == 1) UART_IER3 = 0x01; // if last byte, disable tx int
UART_THR3 = ucUART_xmit_buffer3[uiUART_xmit_nextout3++];
if(uiUART_xmit_nextout3 >= XMIT_BUF_SIZE) uiUART_xmit_nextout3 = 0;
uiUART_xmit_count3--;
}
// service channel 4 transmitter
temp = UART_LSR4;
if (((temp & 0x20) == 0x20) && uiUART_xmit_count4)
{
if(uiUART_xmit_count4 == 1) UART_IER4 = 0x01; // if last byte, disable tx int
UART_THR4 = ucUART_xmit_buffer4[uiUART_xmit_nextout4++];
if(uiUART_xmit_nextout4 >= XMIT_BUF_SIZE) uiUART_xmit_nextout4 = 0;
uiUART_xmit_count4--;
DSK6713_LED_on(3);
}
// If a character is waiting in the UART FIFO, and there
// is room in the receive buffer, get the character, and
// adjust the pointer and count.
// service channel 1 receiver
temp = UART_ISR1;
if ((temp & 0x05) == 0x04)
{
if (uiUART_recv_count1 < RECV_BUF_SIZE)
{
ucUART_recv_buffer1[uiUART_recv_nextin1++] = UART_RBR1;
if(uiUART_recv_nextin1 >= RECV_BUF_SIZE) uiUART_recv_nextin1 = 0;
uiUART_recv_count1++;
}
else
trash = UART_RBR1; // discard char if buffer is full
}
// service channel 2 receiver
temp = UART_ISR2;
if ((temp & 0x05) == 0x04)
{
if (uiUART_recv_count2 < RECV_BUF_SIZE)
{
ucUART_recv_buffer2[uiUART_recv_nextin2++] = UART_RBR2;
if(uiUART_recv_nextin2 >= RECV_BUF_SIZE) uiUART_recv_nextin2 = 0;
uiUART_recv_count2++;
}
else
trash = UART_RBR2; // discard char if buffer is full
}
// service channel 3 receiver
temp = UART_ISR3;
if ((temp & 0x05) == 0x04)
{
if (uiUART_recv_count3 < RECV_BUF_SIZE)
{
ucUART_recv_buffer3[uiUART_recv_nextin3++] = UART_RBR3;
if(uiUART_recv_nextin3 >= RECV_BUF_SIZE) uiUART_recv_nextin3 = 0;
uiUART_recv_count3++;
}
else
trash = UART_RBR3; // discard char if buffer is full
}
// service channel 4 receiver
temp = UART_ISR4;
if ((temp & 0x05) == 0x04)
{
if (uiUART_recv_count4 < RECV_BUF_SIZE)
{
ucUART_recv_buffer4[uiUART_recv_nextin4++] = UART_RBR4;
if(uiUART_recv_nextin4 >= RECV_BUF_SIZE) uiUART_recv_nextin4 = 0;
uiUART_recv_count4++;
}
else
trash = UART_RBR4; // discard char if buffer is full
}
// It is imperative that no interrupts are pending when this ISR
// exits. So check if any more interrupts are pending and service them.
if ((UART_ISR1 & 0x01) == 0) continue;
if ((UART_ISR2 & 0x01) == 0) continue;
if ((UART_ISR3 & 0x01) == 0) continue;
if ((UART_ISR4 & 0x01) == 0) continue;
break;
}
}
int UART_recv_block (int chn, unsigned char* buf, unsigned int length)
{
unsigned int index;
switch (chn)
{
case 1:
if (uiUART_recv_count1 < length) return (-1);
for (index=0; index<length; index++)
{
buf[index] = ucUART_recv_buffer1[uiUART_recv_nextout1++];
if (uiUART_recv_nextout1 >= RECV_BUF_SIZE) uiUART_recv_nextout1=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count1 -= length;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 2:
if (uiUART_recv_count2 < length) return (-1);
for (index=0; index<length; index++)
{
buf[index] = ucUART_recv_buffer2[uiUART_recv_nextout2++];
if (uiUART_recv_nextout2 >= RECV_BUF_SIZE) uiUART_recv_nextout2=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count2 -= length;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 3:
if (uiUART_recv_count3 < length) return (-1);
for (index=0; index<length; index++)
{
buf[index] = ucUART_recv_buffer3[uiUART_recv_nextout3++];
if (uiUART_recv_nextout3 >= RECV_BUF_SIZE) uiUART_recv_nextout3=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count3 -= length;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
case 4:
if (uiUART_recv_count4 < length) return (-1);
for (index=0; index<length; index++)
{
buf[index] = ucUART_recv_buffer4[uiUART_recv_nextout4++];
if (uiUART_recv_nextout4 >= RECV_BUF_SIZE) uiUART_recv_nextout4=0;
}
/* disable interrupts around the following statement */
IRQ_disable(DC_INTERRUPT_SOURCE); // disable external interrupt
uiUART_recv_count4 -= length;
IRQ_enable(DC_INTERRUPT_SOURCE); // enable external interrupt
break;
}
return (0);
}
/* The following delay routine is used to eat up some time during
initialization. For a 6713 running at 225 MHz (i.e. the 6713 DSK),
a value of 8000 passed to this routine causes a delay of
approximately 1 millisecond.
*/
void delay(long value)
{
volatile double x;
long i;
for(i=0;i< value; i++)
{
x=1;
}
}
void irq_ext_enable()
{
// First, globally disable interrupts
// CSR [Control Status Register] Bit 0 is GIE [Global Interrupt Enable]
// Set last bit to ZERO
CSR = (CSR)&(0xFFFFFFFE);
// Set the NMIE bit (bit #1) at the IER
IER |= 0x00000002;
// Set the INT4 bit (bit #4) at the IER
IER |= 0x00000010;
// Last, globally enable interrupts (CSR last bit to 1)
CSR |= 0x00000001;
}
int main()
{ short p=0;
comm_poll(); //.. INITIALIZING POLLING BASED PROGRAM ..//
CE2_CONTROL = 0x03d00f21; // set up CE2 memory space access timing
DC_REG |= 0x08; // raise daughter card reset signal
delay(8000L*250); // delay ~ 250 milliseconds
DC_REG &= ~0x08; // remove daughter card reset signal
delay(8000L*250); // delay ~ 250 milliseconds
CSL_init(); // initialize the Chip Support Library
DSK6713_LED_init();
initialize_UART(1,DATA_RATE_19200); // initialize the uart channels
initialize_UART(2,DATA_RATE_19200); // initialize the uart channels
initialize_UART(3,DATA_RATE_9600); // initialize the uart channels
initialize_UART(4,DATA_RATE_4000); // initialize the uart channels
irq_ext_enable(); //Initialize external interrupt
if(UART_xmit_count(CHANNEL_TO_USE) < 10)
{
UART_send_block(CHANNEL_TO_USE,heading1,strlen(heading1));
}
if(len = UART_recv_count(CHANNEL_TO_USE))
{
UART_recv_block (CHANNEL_TO_USE, buf, len);
}
return 0;
}