ozymandias 7 Posted February 13, 2012 Share Posted February 13, 2012 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. Quote Link to post Share on other sites
RobG 1,892 Posted February 13, 2012 Share Posted February 13, 2012 Never worked for me (example code.) I did get couple of chars echoed correctly at one point, but never got it to work properly at all times. I gave up and switched to 2553. Quote Link to post Share on other sites
SugarAddict 227 Posted February 13, 2012 Share Posted February 13, 2012 //****************************************************************************** // 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... Quote Link to post Share on other sites
SugarAddict 227 Posted February 13, 2012 Share Posted February 13, 2012 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 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } } } ozymandias and bluehash 2 Quote Link to post Share on other sites
ozymandias 7 Posted February 14, 2012 Author Share Posted February 14, 2012 :shock: :shock: It just works! WTF, thats not supposed to happen. Thank you! IOU a drink sir. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.