Jump to content
43oh

G2231 UART echo not quite working


Recommended Posts

So, I have been trying to make a UART to SPI "bridge", so as a first step I'm making a UART echo program to verify that the UART is recieving data correctly.

 

I started with a TI example program which had both TX and RX in one timerA ISR. The program didn't work as it was supposed to, so i kept the TX in the timerA0 ISR and put RX in the timerA1 ISR. This sort-of worked, as it transmitted data back, but the data is invariably 0xFF (though it transmits 0x00 the first time after the chip is programmed).

 

Here is the code, if somebody sees any glaring errors:

 

#include 
#include 

#define RXD      BIT2
#define TXD      BIT1
#define LED2	 BIT6
#define LED1	BIT0

#define Bitime_5  0x06
#define Bitime    0x0E

unsigned int RXTXData;
unsigned char BitCnt;

void TX_Byte (void);
void RX_Ready (void);

int main (void){
WDTCTL = WDTPW + WDTHOLD;
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
CCTL0 = OUT;
TACTL = TASSEL_1 + MC_2;
P1SEL = TXD + RXD;
P1DIR = TXD + LED1 + LED2;

CCTL1 = SCS + OUTMOD0 + CM1 + CAP + CCIE;  

while(1){
	RX_Ready();
	_BIS_SR(CPUOFF + GIE);
	TX_Byte();
}
}

void TX_Byte (void){
BitCnt = 0xA;
while (CCR0 != TAR){
	CCR0 = TAR;
}
CCR0 += Bitime;
RXTXData |= 0x100;
RXTXData = RXTXData << 1;
CCTL0 =  CCIS0 + OUTMOD0 + CCIE;
while ( CCTL0 & CCIE ){}
}

void RX_Ready (void){
BitCnt = 0x8;
CCTL1 = SCS + OUTMOD0 + CM1 + CAP + CCIE;
}

interrupt(TIMERA0_VECTOR) Timer_A0(void){

CCR0 += Bitime;

if (CCTL0 & CCIS0){
	if ( BitCnt == 0){
		CCTL0 &= ~ CCIE;
	}else{
		CCTL0 |=  OUTMOD2;
		if (RXTXData & 0x01){
			CCTL0 &= ~ OUTMOD2;
		}
		RXTXData = RXTXData >> 1;
		BitCnt --;
	}
}
}

interrupt(TIMERA1_VECTOR) Timer_A1(void){

CCR1 += Bitime; 

if(CCTL1 & CAP){
	CCTL1 &= ~ CAP;
	CCR1 += Bitime_5;
}else{
	RXTXData = RXTXData >> 1;
	if (CCTL1 & SCCI){
		RXTXData |= 0x80;
	}
	BitCnt --;

	if ( BitCnt == 0){
		P1OUT ^= LED2;
		CCTL1 &= ~ CCIE;
		_BIC_SR_IRQ(LPM3_bits);
	}
}
}

 

Sorry there aren't any proper comments.

 

EDIT: forgot to mention that this is a MSP430G2231 on the launchpad with a 32KHz crystal, and the UART is set for 2400 8N1. LED2 does indeed toggle when data is sent to the chip and if one assigns a value to RXTXData, it does transmit that byte successfully.

Link to post
Share on other sites

//******************************************************************************
//  MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 2400 Echo, 32kHz ACLK
//
//  Description: Use Timer_A CCR0 hardware output modes and SCCI data latch
//  to implement UART function @ 2400 baud. Software does not directly read and
//  write to RX and TX pins, instead proper use of output modes and SCCI data
//  latch are demonstrated. Use of these hardware features eliminates ISR
//  latency effects as hardware insures that output and input bit latching and
//  timing are perfectly synchronised with Timer_A regardless of other
//  software activity. In the Mainloop the UART function readies the UART to
//  receive one character and waits in LPM3 with all activity interrupt driven.
//  After a character has been received, the UART receive function forces exit
//  from LPM3 in the Mainloop which echo's back the received character.
//  ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO
//  //* An external watch crystal is required on XIN XOUT for ACLK *//
//
//               MSP430G2xx1
//            -----------------
//        /|\|              XIN|-
//         | |                 | 32kHz
//         --|RST          XOUT|-
//           |                 |
//           |   CCI0B/TXD/P1.5|-------->
//           |                 | 2400 8N1
//           |   CCI0A/RXD/P1.1|<--------
//
#define RXD       0x02                      // RXD on P1.1
#define TXD       0x20                      // TXD on P1.5

//   Conditions for 2400 Baud SW UART, ACLK = 32768

#define Bitime_5  0x06                      // ~ 0.5 bit length + small adjustment
#define Bitime    0x0E                      // 427us bit length ~ 2341 baud

unsigned int RXTXData;
unsigned char BitCnt;

void TX_Byte (void);
void RX_Ready (void);

//  D. Dang
//  Texas Instruments Inc.
//  October 2010
//  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************

#include  


int main (void)
{
 WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
 CCTL0 = OUT;                              // TXD Idle as Mark
 TACTL = TASSEL_1 + MC_2;                  // ACLK, continuous mode
 P1SEL = TXD + RXD;                        //
 P1DIR = TXD;                              //

// Mainloop
 for (;
 {
 RX_Ready();                               // UART ready to RX one Byte
 _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interr until char RXed
 TX_Byte();                                // TX Back RXed Byte Received
 }
}


// Function Transmits Character from RXTXData Buffer
void TX_Byte (void)
{
 BitCnt = 0xA;                             // Load Bit counter, 8data + ST/SP
 while (CCR0 != TAR)                       // Prevent async capture
   CCR0 = TAR;                             // Current state of TA counter
 CCR0 += Bitime;                           // Some time till first bit
 RXTXData |= 0x100;                        // Add mark stop bit to RXTXData
 RXTXData = RXTXData << 1;                 // Add space start bit
 CCTL0 =  CCIS0 + OUTMOD0 + CCIE;          // TXD = mark = idle
 while ( CCTL0 & CCIE );                   // Wait for TX completion
}


// Function Readies UART to Receive Character into RXTXData Buffer
void RX_Ready (void)
{
 BitCnt = 0x8;                             // Load Bit counter
 CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE;   // Sync, Neg Edge, Cap
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
interrupt void Timer_A (void)
{
 CCR0 += Bitime;                           // Add Offset to CCR0

// TX
 if (CCTL0 & CCIS0)                        // TX on CCI0B?
 {
   if ( BitCnt == 0)
   CCTL0 &= ~ CCIE;                        // All bits TXed, disable interrupt
   else
   {
     CCTL0 |=  OUTMOD2;                    // TX Space
     if (RXTXData & 0x01)
     CCTL0 &= ~ OUTMOD2;                   // TX Mark
     RXTXData = RXTXData >> 1;
     BitCnt --;
   }
 }
// RX
 else
 {
   if( CCTL0 & CAP )                       // Capture mode = start bit edge
   {
   CCTL0 &= ~ CAP;                         // Switch from capture to compare mode
   CCR0 += Bitime_5;
   }
   else
   {
   RXTXData = RXTXData >> 1;
     if (CCTL0 & SCCI)                     // Get bit waiting in receive latch
     RXTXData |= 0x80;
     BitCnt --;                            // All bits RXed?
     if ( BitCnt == 0)
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     {
     CCTL0 &= ~ CCIE;                      // All bits RXed, disable interrupt
     _BIC_SR_IRQ(LPM3_bits);               // Clear LPM3 bits from 0(SR)
     }
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   }
 }
}

 

The TI example, with slight changes to compile as .cpp (comes as .c) pasted above works fine on a REV 1.5 LP with P1.1 wired to upper right and P1.5 wired to lower left... as seen in photo...

post-463-135135538011_thumb.jpg

Link to post
Share on other sites

Here is the example with LED1 and LED2 modification so you can see that it is actually working. Each character RX/TX will toggle the active LED back and forth.

 

//******************************************************************************
//  MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 2400 Echo, 32kHz ACLK
//
//  Description: Use Timer_A CCR0 hardware output modes and SCCI data latch
//  to implement UART function @ 2400 baud. Software does not directly read and
//  write to RX and TX pins, instead proper use of output modes and SCCI data
//  latch are demonstrated. Use of these hardware features eliminates ISR
//  latency effects as hardware insures that output and input bit latching and
//  timing are perfectly synchronised with Timer_A regardless of other
//  software activity. In the Mainloop the UART function readies the UART to
//  receive one character and waits in LPM3 with all activity interrupt driven.
//  After a character has been received, the UART receive function forces exit
//  from LPM3 in the Mainloop which echo's back the received character.
//  ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO
//  //* An external watch crystal is required on XIN XOUT for ACLK *//
//
//               MSP430G2xx1
//            -----------------
//        /|\|              XIN|-
//         | |                 | 32kHz
//         --|RST          XOUT|-
//           |                 |
//           |   CCI0B/TXD/P1.5|-------->
//           |                 | 2400 8N1
//           |   CCI0A/RXD/P1.1|<--------
//
#define RXD       0x02                      // RXD on P1.1
#define TXD       0x20                      // TXD on P1.5
#define LED1      0x01
#define LED2      0x40

//   Conditions for 2400 Baud SW UART, ACLK = 32768

#define Bitime_5  0x06                      // ~ 0.5 bit length + small adjustment
#define Bitime    0x0E                      // 427us bit length ~ 2341 baud

unsigned int RXTXData;
unsigned char BitCnt;

void TX_Byte (void);
void RX_Ready (void);

//  D. Dang
//  Texas Instruments Inc.
//  October 2010
//  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************

#include  


int main (void)
{
 WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
 CCTL0 = OUT;                              // TXD Idle as Mark
 TACTL = TASSEL_1 + MC_2;                  // ACLK, continuous mode
 P1SEL = TXD + RXD;                        //
 P1DIR = TXD + LED1 + LED2;                //

// Mainloop
 for (;
 {
 RX_Ready();                               // UART ready to RX one Byte
 P1OUT ^= LED1;
 _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interr until char RXed
 TX_Byte();                                // TX Back RXed Byte Received
 P1OUT ^= LED2;
 }
}


// Function Transmits Character from RXTXData Buffer
void TX_Byte (void)
{
 BitCnt = 0xA;                             // Load Bit counter, 8data + ST/SP
 while (CCR0 != TAR)                       // Prevent async capture
   CCR0 = TAR;                             // Current state of TA counter
 CCR0 += Bitime;                           // Some time till first bit
 RXTXData |= 0x100;                        // Add mark stop bit to RXTXData
 RXTXData = RXTXData << 1;                 // Add space start bit
 CCTL0 =  CCIS0 + OUTMOD0 + CCIE;          // TXD = mark = idle
 while ( CCTL0 & CCIE );                   // Wait for TX completion

}


// Function Readies UART to Receive Character into RXTXData Buffer
void RX_Ready (void)
{
 BitCnt = 0x8;                             // Load Bit counter
 CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE;   // Sync, Neg Edge, Cap
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
interrupt void Timer_A (void)
{
 CCR0 += Bitime;                           // Add Offset to CCR0

// TX
 if (CCTL0 & CCIS0)                        // TX on CCI0B?
 {
   if ( BitCnt == 0)
   CCTL0 &= ~ CCIE;                        // All bits TXed, disable interrupt
   else
   {
     CCTL0 |=  OUTMOD2;                    // TX Space
     if (RXTXData & 0x01)
     CCTL0 &= ~ OUTMOD2;                   // TX Mark
     RXTXData = RXTXData >> 1;
     BitCnt --;
   }
 }
// RX
 else
 {
   if( CCTL0 & CAP )                       // Capture mode = start bit edge
   {
   CCTL0 &= ~ CAP;                         // Switch from capture to compare mode
   CCR0 += Bitime_5;
   }
   else
   {
   RXTXData = RXTXData >> 1;
     if (CCTL0 & SCCI)                     // Get bit waiting in receive latch
     RXTXData |= 0x80;
     BitCnt --;                            // All bits RXed?
     if ( BitCnt == 0)
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     {
     CCTL0 &= ~ CCIE;                      // All bits RXed, disable interrupt
     _BIC_SR_IRQ(LPM3_bits);               // Clear LPM3 bits from 0(SR)
     }
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   }
 }
}

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...