Jump to content
43oh

BETA G2231 UART RX/SPI TX and SPI RX/ stepper signals


Recommended Posts

Project: control 3 MSP430G2231's using a single G2231 as a bridge/converter/demultiplexer that recieves data through the USB

 

the bridge takes bytes and puts alternately sends them to recievers 1-3.

 

the recievers' P1.0 and P1.6 go to stepper motor controllers to step on rising edge and control direction, respectively.

 

"bridge" part:

-recieves bytes from 2400 8N1 input to P1.1 (requires launchpad 'RXD' jumper to be removed and the pin on the FTDI side connected to P1.1)

 

-after reception, transmits each byte out of P1.6 as MOSI and P1.5 as SCLK.

 

-cycles through bringing one of three output pins low as a chip select

 

#include 
#include 

//   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
#define RXD       0x02          
#define TXD       0x20                  
#define LED1      0x01
#define LED2      0x40

unsigned char RXTXData;
unsigned char BitCnt;
unsigned char temp;

static void __inline__ delay(register unsigned int n);

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 + BIT4 + BIT3;
P1OUT = LED1 + BIT4 + BIT3;
USICTL0 = USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE | USISWRST; // Port, SPI Master
USICTL1 = USICKPH | USIIE;
USICKCTL = 0xE4;// /128 aclk?

temp = 0;

     while(1){
	P1OUT |= LED1 + BIT4 + BIT3;
	BitCnt = 0x8;                             // Load Bit counter
	CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE;   // Sync, Neg Edge, Cap
	_BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interr until char RXed

	if(temp == 2){
		temp = 0;
	}else{
		temp = temp +1;
	}
}
}

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

       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){

		USISRL = RXTXData;
		if(temp == 0){
			P1OUT &= ~LED1;
			P1OUT |= BIT4 + BIT3;
		}else if(temp == 1){
			P1OUT &= ~BIT4;
			P1OUT |= LED1 + BIT3;
		}else if(temp == 2){
			P1OUT &= ~BIT3;
			P1OUT |= LED1 + BIT4;
		}
		USICNT |= 0x08;
		USICTL0 &= ~USISWRST;
		while (!(USIIFG & USICTL1));
		USICTL0 |= USISWRST;
		delay(0);
		P1OUT |= LED1 + BIT4 + BIT3;

		CCTL0 &= ~ CCIE;                      // All bits RXed, disable interrupt

		_BIC_SR_IRQ(LPM3_bits + GIE);               // Clear LPM3 bits from 0(SR)

	}
}
}

static void __inline__ delay(register unsigned int n)
{
 __asm__ __volatile__ (
 "1: \n"
 " dec %[n] \n"
 " jne 1b \n"
       : [n] "+r"(n));
}

 

The reciever recieves the byte from the bridge and in state machine fashion puts the byte in:

-a counter for number of steps to take

-determines to set or clear a direction bit

-sets TACCR0 to control toggle rate

 

#include 
#include 

unsigned int bufff;
unsigned char count;

int main(void){
WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
P1OUT =  0x00;                        // P1.4 set, else reset
P1DIR = 0x01 + BIT6;                         // P1.0 output, else input
USICTL0 |= USIPE7 + USIPE5; // Port, SPI slave
USICTL1 |= USIIE;                     // Counter interrupt, flag remains set
USICTL0 &= ~USISWRST;                 // USI released for operation
USICNT = 8;                           // init-load counter
bufff = 0;
count = 0;
TACTL = TASSEL_1 | MC_1;	//Set TimerA to use auxiliary clock in UP mode
TACCTL0 = CCIE;	//Enable the interrupt for TACCR0 match
TACCR0 = 2;	

_BIS_SR(LPM0_bits + GIE);             // Enter LPM0 w/ interrupt
while(1){
}
}

// USI interrupt service routine
interrupt(USI_VECTOR) universal_serial_interface(void){

if(count == 0){//bufff
	if(USISRL > 0x7A){
		bufff = bufff + 0xFF00;
	}else{
		bufff = bufff + USISRL;
	}
}else if(count == 1){//dir
	if(USISRL > 0x3F){
		P1OUT |= BIT6;
	}else{
		P1OUT &= ~BIT6;
	}
}else if(count == 2){//speed
	TACCR0 = USISRL;
}else{
	count = 0;
}
count = count + 1;
if(count == 3){
	count = 0;
}

USICNT = 8;                           // re-load counter
}

interrupt(TIMERA0_VECTOR) TIMERA0_ISR(void) {

if( bufff > 0){
	P1OUT ^= BIT0;
	bufff = bufff - 1;
}
}

 

PROBLEMS:

-the bridge can't pass data through it too fast. one must wait about ~200ms until the next byte is sent to prevent data loss. (the code isn't optimized and kinda "fatty" in all likelihood).

-since the TimerA assignments from USI data occur in the USI-ISR (and i haven't found a reliable way to do it otherwise), the data isn't 'pushed' into TimerA until the next byte is recieved.

-it would be cool to not have to modify the jumpers on the launchpad to do the UART, but its based on TI code that worked so i went with it.

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...