SparkFun Forums 

Where electronics enthusiasts find answers.

Discussions on how to get your MSP JTAG programmer up and running.
By snowzach
#133492
Has anyone gotten these to work with the MSP430's? I've seen some posts but nothing complete... I've been working on this for about 2-3 weeks and have nearly given up. Here's my code thus far. Ive tried SW and HW SPI. Here's the software one because it should be easier to read. I've borrowed some of the JeeNode code as well as some code from anything I could find to get it to work. I would like to be able to send a packet to my JeeNode. With HW SPI I just seem to see POR set in the status all the time (power is good)
Code: Select all
//           RFM12 Transceiver              MSP430F2013
//             -----------------          -----------------
//            |                 |        |              XIN|-
//            |                 |        |                 |
//            |                 |        |             XOUT|-
//       VCC->|VDD              |        |                 |
//            |                 |        |                 |
//      GND ->|GND (7&10)  nIRQ |------->|P1.3             |
//            |            nSEL |<-------|P1.2         P1.0|-> LED1
//            |             SDI/|<-------|P1.6/SDO     P1.1|-> LED2
//            |             SDO/|------->|P1.7/SDI         |
//            |            SCLK/|<-------|P1.5/SCLK        |
//             -----------------          -----------------

#include <msp430x20x3.h>
#include <stdint.h>

static uint8_t nodeid;		// address of this node
static uint8_t group;		// network group
volatile uint16_t crc;		// network group
uint16_t ret;

#define RF12_433MHZ     1
#define RF12_868MHZ     2
#define RF12_915MHZ     3

// RF12 command codes
#define RF_RECEIVER_ON  0x82DD
#define RF_XMITTER_ON   0x823D
#define RF_IDLE_MODE    0x820D
#define RF_SLEEP_MODE   0x8205
#define RF_WAKEUP_MODE  0x8207
#define RF_TXREG_WRITE  0xB800
#define RF_RX_FIFO_READ 0xB000
#define RF_WAKEUP_TIMER 0xE000

// Delays by the specified Millisecondsvoid delay(unsigned int ms)
void delay(uint16_t ms) {
	while (ms--) {
        __delay_cycles(8000); // set for 16Mhz change it to 1000 for 1 Mhz
    }
}

// CRC Calculating function
unsigned int crc16_update(uint16_t crc, uint8_t a) {
	uint8_t i;

	crc ^= a;
	for(i=0; i<8; ++i) {
		if(crc&1)
			crc = (crc>>1) ^ 0xA001;
		else
			crc = (crc>>1);
	}
	return crc;
}
	
uint16_t spi_xfer(uint16_t value) {
	uint16_t ret = 0x0000;
	uint8_t x;
	
	P1OUT &= ~0x20;			// P1.5=SCK=LOW
	P1OUT &= ~0x04;			// P1.2 LOW = nSEL (Wireless module selected)
	
	for(x=0; x<16; x++) {
		if(value & 0x8000) {
			P1OUT |= 0x40;	// P1.6=SDI=HI		
		} else {
			P1OUT &= ~0x40;	// P1.6=SDI=LOW
		}
		P1OUT |= 0x20;		// P1.5=SCK=HI
		value <<= 1;
		ret <<= 1;
		if(P1IN & 0x80) ret |= 0x0001;
		P1OUT &= ~0x20;		// P1.5=SCK=LOW
	}
	P1OUT |= 0x04;			// P1.2 LOW = nSEL (Wireless module selected)
	return ret;				// This is the value SPI'ed out of the RF12b
}

void rf12_init(uint16_t id, uint16_t band, uint16_t g) {
	nodeid = id;
	group = g;
	
	spi_xfer(0x0000);			//Blank it out
	spi_xfer(RF_IDLE_MODE);	// Turn off all the radios
	
	spi_xfer(RF_TXREG_WRITE); 	// Send blank packet (resets the radio)
	while((P1IN & 0x08) == 0) { // Wait until IRQ
		spi_xfer(0x0000);
	}
	
	spi_xfer(0x80C7 | (band << 4)); // EL (ena TX), EF (ena RX FIFO), 12.0pF 
	spi_xfer(0xA640); // 868MHz 
	spi_xfer(0xC606); // approx 49.2 Kbps, i.e. 10000/29/(1+6) Kbps
	spi_xfer(0x94A2); // VDI,FAST,134kHz,0dBm,-91dBm 
	spi_xfer(0xC2AC); // AL,!ml,DIG,DQD4 
	if(group != 0) {
		spi_xfer(0xCA83); // FIFO8,2-SYNC,!ff,DR 
		spi_xfer(0xCE00 | group); // SYNC=2DXX
	} else {
		spi_xfer(0xCA8B); // FIFO8,1-SYNC,!ff,DR 
		spi_xfer(0xCE2D); // SYNC=2D
	} 
	spi_xfer(0xC483); // @PWR,NO RSTRIC,!s,!fi,OE,EN 
	spi_xfer(0x9850); // !mp,90kHz,MAX OUT 
	spi_xfer(0xCC77); // OB1,OB0, LPX,!ddy,DDIT,BW0 
	spi_xfer(0xE000); // NOT USE 
	spi_xfer(0xC800); // NOT USE 
	spi_xfer(0xC049); // 1.66MHz,3.1V
}

void rf12_send(uint8_t value) {
	while(P1IN & 0x08) ;		// When it's low, TXREG is ready to receive the next byte
	spi_xfer(RF_TXREG_WRITE + value); 	// Send it
}

void main(void)
{
	WDTCTL = WDTPW + WDTHOLD;       // Stop watchdog timer
	DCOCTL = CALDCO_8MHZ;			// Set DCO step + modulation to 8MHZ Calibrated
	BCSCTL1 = CALBC1_8MHZ;			// Set Clock to 8MHZ

	P1DIR |= 0x67; 					// OUTPUTS = P1.0=LED1, P1.1=LED2, P1.2=nSEL=HIGH, P1.5=SCK, P1.6=SDI
	P1DIR &= ~0x88;					// INPUTS = P1.3=nIRQ, P1.7=SDO
	P1OUT = 0x04;

	// Initialize the rf12
	rf12_init(10, RF12_915MHZ, 212);  // Node 10, 3 = 915MHZ, Group 212
	spi_xfer(RF_XMITTER_ON);
	
	while(1) {
		rf12_send(0xAA); // PREAMBLE
		rf12_send(0xAA); // PREAMBLE
		rf12_send(0xAA); // PREAMBLE
		rf12_send(0x2D); // SYNC1
		rf12_send(0xD4); crc = crc16_update(~0, 0xD4); // SYNC2
		rf12_send(0x41); crc = crc16_update(crc, 0x41); // C=0 D=1 A=0 NODE=1 http://jeelabs.org/2011/06/10/rf12-broadcasts-and-acks/
		rf12_send(0x04); crc = crc16_update(crc, 0x04); // LENGTH = 4
		rf12_send(0x48); crc = crc16_update(crc, 0x48); // H
		rf12_send(0x49); crc = crc16_update(crc, 0x49); // I
		rf12_send(0x48); crc = crc16_update(crc, 0x48); // H
		rf12_send(0x49); crc = crc16_update(crc, 0x49); // I
		rf12_send(crc);									// CRC1
		rf12_send(crc >> 8);							// CRC2
		rf12_send(0x00);								// DUMMY BYTE
		ret = spi_xfer(0x0000);
		delay(3000);									// Wait 3 seconds
	}	
}