Jump to content
43oh

16 Bit SPI Help


Recommended Posts

I am trying to get some SPI test code working.

I want to send a 16 bit value to the Launch pad and have it return a predetermined 16 bit value.

For example: Send 0x00F1 and receive 0x0035 from the Launchpad.

I am currently only getting 0x0000 back and 0x00F1 or 0x00F0 depending on what is sent.

It appears to be only echoing the values sent back to me instead of sending the correct response.

 

Thanks!

#include 
#include 					// Intrinsic functions
#include 						// Integers of defined sizes


volatile unsigned int SERVO_0 = 0x0045;
volatile unsigned int SERVO_1 = 0x0035;

void main(void)
{

 WDTCTL = WDTPW + WDTHOLD;   					// Stop watchdog timer

 //Load 1Mhz Factory Calibrated Values.
 BCSCTL1 = CALBC1_1MHZ; 						// Set range
 DCOCTL = CALDCO_1MHZ;  						// Set DCO step and modulation

 USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIOE; 	// Port, SPI slave
 USICTL1 |= USIIE + USICKPH;                   // Counter interrupt, flag remains set
 USICTL0 &= ~USISWRST;                 		// USI released for operation
 USISR = 0x0000;                        		// init-load data, USISR-USI Shift Register, where the data is kept
 USICNT = USI16B | 16;               	// init-load counter, USICNT-USI Bit Count Register, number of bits to be sent

 while(1)//loop
 {

 _BIS_SR(GIE);             // interrupt enable
 __low_power_mode_3();			// Only ACLK continues to run

 }
}



// *****************************USI interrupt service routine********************
#pragma vector=USI_VECTOR
__interrupt void universal_serial_interface(void)
{
 if (0xF0 == USISRL)			//return values of servo signal from requested servo
 {
  USISR = SERVO_0;
  USICNT = USI16B | 16;
 }

 if (0xF1 == USISRL)
   {
 	  USISR = SERVO_1;
 	  USICNT = USI16B | 16;
   }

 else
 {
  USISR = 0x0000;
  USICNT = USI16B | 16;
 }
}

Link to post
Share on other sites

Not sure exactly what is wrong. Give this a try...

 

// *****************************USI interrupt service routine********************
#pragma vector=USI_VECTOR
__interrupt void universal_serial_interface(void)
{
   switch(USISRL) {
       case 0xF0: USISR = SERVO_0; break;
       case 0xF1: USISR = SERVO_1; break;
       default:   USISR = 0x0000;  break;
   }
   USICNT = USI16B | 16;
}

 

The structure of this code ensures that the data latch is only read once, and the bit count is only set once.

Link to post
Share on other sites
Could the msp not be processing fast enough? If the master is clocking the spi line before the msp has processed the data and loaded the usi buffer (same buffer for in and out, right?), the msp is just sending back whatever is in the buffer?

you might be on to something...

 

oPossum: I am going to try your code tonight.

Link to post
Share on other sites
Currently I am sending two bytes consecutively, MSB. The clock is 400KHz.

I am reading the correct received value on USISR with the debugger.

I am thinking the problem lies in the processing of the input data and returning the value.

 

I think you need to send 4 bytes. The first 16 bits are shifted out when you send 2 bytes from the

bus pirate. That returns your initial 0x0000 value. The next 16 bits will be returned when you send

another 16 bits. Typically people use a dummy byte of 0xFF. You want to transfer 16 bits so you need

to send 0xFFFF.

 

-rick

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