This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi everybody,
Can someone please give me some hints/direction of why the code below is not
working.
I tested the pin on the RESET and SSNOT, there are signal, but for the SPI module
(UCB0MOSI, UCB0SOMI, CLK), there are no signals. my PNI sensor/hardware should be
working fine since it works with another processor.
I believed the mistakes are probably in the regsister setting (which I don't know).
PLEASE HHHHEEEELLLLPPPP! Thanks in advance!
Hardware used:
The eZ430-RF2500 is a complete USB-based MSP430 wireless
development tool providing all the hardware and software to evaluate the
MSP430F2274 microcontroller and CC2500 2.4-GHz wireless transceiver.
PNI MicroMag 2 2-Axis Magnetic Sensor ModuleThe MicroMag2 is an integrated 2-axis
magnetic field sensing module designed to aid in evaluation nd prototyping of PNI
Corporation’s technology.
Name: MicroMag2
Part: 11594 (from PNI)
// |PNI MicroMag 2| |eZ430-RF2500 Dev tool (access pin 1 to pin 18)
// | | | --------------------|
// | #6-RESET|<---|P2.0-#3 |
// | #5-DRDY|--->|P2.1-#4 |
// | #3-UCB0MOSI|<---|P3.1-#UCB0SIMO#18 |
// | #4-SSNOT|<---|P3.0-#17 |
// | #2-DATAOUT|--->|P3.2/UCB0SOMI-#15 |
// | #1-CLK|<---|P3.3/UCB0CLK-#16 |
// | #7-GND|----|GND-#1 |
// | #12-AVDD| |VCC-#2 |
void PNI_sensor(void)
{
BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8MHz
DCOCTL = CALDCO_8MHZ;
// port setup
P2DIR |= 0x01; //b00000001; 1=ouput
//P3DIR |= 0x01; //b00000001
P3DIR |= 0x0B; //b00001011
P3SEL |= 0x0E; //b00001110
// Data is captured by the master device on the rising edge of SCLK. Data is //
shifted out and presented to
// the MicroMag2 on the MOSI pin on the falling edge of SCLK.
// UCCKPL = 0: The inactive state is low
UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI mstr, MSB Ist
UCB0CTL1 |= UCSSEL_2; // use clock signal SMCLK
UCB0BR0 = 0x0A;
UCB0BR1 = 0x00; // high-byte 8 bit
// brad rate = BRCLK = SMCLK/10
UCB0CTL1 &= ~UCSWRST; // Initialize USCI state machine
// not using ISR
//IE2 |= UCB0RXIE + UCB0TXIE;
// set SSNOT P3.0 to low
P3OUT &= ~0x01;
// toggle reset high-low
for (int i = 10; i > 0; i--);
P2OUT |= 0x01;
for (int i = 20; i > 0; i--);
P2OUT &= ~0x01;
for (int i = 20; i > 0; i--);
// command byte(MST_Data) [7-0]:DHST PS2 PS1 PS0 ODIR MOT ASI ASO
// 0b01110001--> 0x71
IFG2 &= ~UCB0RXIFG;
UCB0TXBUF = 0x71; // Transmit first character
while(!(0x02 & P2IN));
UCB0TXBUF = 0x00; // Transmit first character
UCB0TXBUF = 0x00; // Transmit second character
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 Rx buffer ready
msg[6] = UCB0RXBUF;
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 Rx buffer ready?
msg[7] = UCB0RXBUF; // get the lower 8 bits
P3OUT |= 0x01; // set SSNOT back to high
}
The operation of the PNI MicroMag 2 (2-Axis Magnetic Sensor Module):
1. SSNOT is brought low.
2. Pulse RESET high (return to low state). You must RESET the MicroMag2 before
every measurement.
3. Data is clocked in on the MOSI line. Once eight bits are read in, the MicroMag2
will execute the command.
4. The MicroMag2 will make the measurement. A measurement consists of forward
biasing the sensor and making a period count; then reverse biasing the sensor and
counting again; and finally, taking the difference between the two bias directions.
5. At the end of the measurement, the DRDY line is set to high indicating that the
data is ready. In response to the next 16 SCLK pulses, data is shifted out on the
MISO line.
If you need to make another measurement, go to Step 2. You can send another command
after the reset.In this case, keep SSNOT low. If you will not be using the
MicroMag2, set SSNOT to high to disable the SPI port.
Zita,
I don't think I completely understand your post. I need the basics [:)]
I get it that you are having SPI troubles, but first let me understand: Are you trying to interface the MSP430 on the EZ-target board to an external device using the SPI on channel B0? Or are you trying to communicate with the CC2500.
I am trying to interface the MSP430 on the EZ-target board to an external device
using the SPI on channel B0. I am using the wireless temperature-sensor network
demonstration application provided with the eZ430-RF2500 development tool to
develop my code (i.e I want to use wireless as well).
The temperature-sensor application uses Texas Instruments SimpliciTI™ wireless
communication protocol to set up a simple network in which end devices communicate
sampled temperature and voltage data to a network access point. The access point
communicates all collected data through an available UART to a PC COM port.The
eZ430-RF2500T target board is an out-of-the-box wireless system that may be used
with the USB debugging interface, as a stand-alone system with or without external
sensors, or incorporated into an existing design. The new USB debugging interface
enables eZ430-RF2500 to remotely send and receive data from a PC using the MSP430
application UART, referred to as the application backchannel.
There are two eZ430-RF2500T target boards, I use one of them as access piont, the
other one I am using to interface with my periperal, and get data from the
periperal/my sensor and send to the access point->pc.
Due to the convenience, I want to use the 18 access pins to connect to my periperal
(i.e. this limits me the choice of pins to use)
The eZ430-RF2500 USB debugging and programming interface
// GMI_sensor micro-controller P1-P18 access pins
// -----------------
// | #6-RESET|<--- |P2.0-#3 |
// | #5-DRDY|---> |P2.1-#4 |
// | #3-UCB0MOSI|<--- |P3.1-#UCB0SIMO-#18 |
// | #4-SSNOT|<--- |P3.0-#17 |
// | #2-DATAOUT|---> |P3.2/UCB0SOMI-#15 |
// | #1-CLK|<--- |P3.3/UCB0CLK-#16 |
// | #7-GND|---- |GND-#1 |
// | #12-AVDD| |VCC-#2 |
Initially I thought there is problem with my register setting in the code ( see
previous message). However, after hooking up the pins in the oscilloscope, I
realized some of the pins that I am using for the SPI module seemed to be
controlled by "something else". When I just hooked up some of the SPI module pins
to oscillcope, there is signal by itself. Now, I am suspecting the wireless
temperature-sensor network demonstration application may be controlling some of the
pins. However, I don't really know exactly which pins and how to disable them.
(i.e. I want to have control over the pins and do SPI interface). If someone is
familiar with the wireless temperature-sensor code, PLEASE let me know which
portion of the codes are doing that.
thanks,
zita
Just to be clear...below is my code for the end device side....the part of the code that I added are bolded...any help will be really appreciated..
#include "bsp.h"
#include "mrfi.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "vlo_rand.h"
void GMI_sensor(void);
void linkTo(void);
void MCU_Init(void);
static uint8_t msg[9]={0xff,0xff ,0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff};
__no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set randomly
void createRandomAddress();
void main (void)
{
addr_t lAddr;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
// delay loop to ensure proper startup before SimpliciTI increases DCO
// This is typically tailored to the power supply used, and in this case
// is overkill for safety due to wide distribution.
volatile int i;
for(i = 0; i < 0xFFFF; i++){}
}
if( CALBC1_8MHZ == 0xFF ) // Do not run if cal values are erased
{
volatile int i;
P1DIR |= 0x03;
BSP_TURN_ON_LED1();
BSP_TURN_OFF_LED2();
while(1)
{
for(i = 0; i < 0x5FFF; i++){}
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
// SimpliciTI will change port pin settings as well
P1DIR = 0xFF;
P1OUT = 0x00;
P2DIR = 0x27;
P2OUT = 0x00;
P3DIR = 0xC0;
P3OUT = 0x00;
P4DIR = 0xFF;
P4OUT = 0x00;
BSP_Init();
if( Flash_Addr[0] == 0xFF &&
Flash_Addr[1] == 0xFF &&
Flash_Addr[2] == 0xFF &&
Flash_Addr[3] == 0xFF )
{
createRandomAddress(); // set Random device address at initial startup
}
lAddr.addr[0]=Flash_Addr[0];
lAddr.addr[1]=Flash_Addr[1];
lAddr.addr[2]=Flash_Addr[2];
lAddr.addr[3]=Flash_Addr[3];
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
BCSCTL1 = CALBC1_8MHZ; // Set DCO after random function
DCOCTL = CALDCO_8MHZ;
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 12000; // ~ 1 sec
TACTL = TASSEL_1 + MC_1; // ACLK, upmode
// keep trying to join until successful. toggle LEDS to indicate that
// joining has not occurred. LED3 is red but labeled LED 4 on the EXP
// board silkscreen. LED1 is green.
while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
{
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();;
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
}
// unconditional link to AP which is listening due to successful join.
linkTo();
}
void createRandomAddress()
{
unsigned int rand, rand2;
do
{
rand = TI_getRandomIntegerFromVLO(); // first byte can not be 0x00 of 0xFF
}
while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
rand2 = TI_getRandomIntegerFromVLO();
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator
FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
Flash_Addr[0]=(rand>>8) & 0xFF;
Flash_Addr[1]=rand & 0xFF;
Flash_Addr[2]=(rand2>>8) & 0xFF;
Flash_Addr[3]=rand2 & 0xFF;
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
}
//
// GMI_sensor micro-controller
// -----------------
// | #6-RESET|<---|P2.0-#3 |
// | #5-DRDY|--->|P2.1-#4 |
// | #3-UCB0MOSI|<---|P3.1-#UCB0SIMO#18 |
// | #4-SSNOT|<---|P3.0-#17 |
// | #2-DATAOUT|--->|P3.2/UCB0SOMI-#15 |
// | #1-CLK|<---|P3.3/UCB0CLK-#16 |
// | #7-GND|----|GND-#1 |
// | #12-AVDD| |VCC-#2 |
void linkTo()
{
linkID_t linkID1;
// keep trying to link...
while (SMPL_SUCCESS != SMPL_Link(&linkID1))
{
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();
}
// Turn off all LEDs
if (BSP_LED1_IS_ON())
{
BSP_TOGGLE_LED1();
}
if (BSP_LED2_IS_ON())
{
BSP_TOGGLE_LED2();
}
while (1)
{
GMI_sensor();
if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
{
BSP_TOGGLE_LED2();
}
else
{
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
}
void GMI_sensor(void)
{
// port setup
P2DIR |= 0x01; //b00000001; 1=ouput
//P3DIR |= 0x01; //b00000001
P3DIR |= 0x0B; //b00001011
P3SEL |= 0x0E; //b00001110
// Data is captured by the master device on the rising edge of SCLK.
// Data is shifted out and presented to
// the MicroMag2 on the MOSI pin on the falling edge of SCLK.
UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI mstr, M
UCB0CTL1 |= UCSSEL_2; // use clock signal SMCLK
//The 16-bit value of (UCxxBR0 + UCxxBR1 × 256) forms the prescaler value.
UCB0BR0 = 0x0A;
UCB0BR1 = 0x00;
UCB0CTL1 &= ~UCSWRST; // Initialize USCI state machine
// set SSNOT P3.0 to low
P3OUT &= ~0x01;
// toggle reset
for (int i = 10; i > 0; i--);
P2OUT |= 0x01;
for (int i = 20; i > 0; i--);
P2OUT &= ~0x01;
for (int i = 20; i > 0; i--);
// z:send command byte(MST_Data) [7-0]:DHST PS2 PS1 PS0 ODIR MOT ASI ASO
// [7-0]: 0b01110001--> 0x71 // brad: 0b01110001--> 0x71
UCB0TXBUF = 0x71; // Transmit first character
while (!(0x02 & P2IN));
UCB0TXBUF = 0x00; // Transmit first character
UCB0TXBUF = 0x00; // Transmit first character
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 TX buffer ready?
msg[6] = UCB0RXBUF;
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 TX buffer ready?
msg[7] = UCB0RXBUF; // get the lower 8 bits
P3OUT |= 0x01; // set SSNOT back to high
}
/*------------------------------------------------------------------------------
* ADC10 interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}
/*------------------------------------------------------------------------------
* Timer A0 interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
__bic_SR_register_on_exit(LPM3_bits); // Clear LPM3 bit from 0(SR)
}
Just to be clear...below is my code for the access point side....the part of the code that I added are bolded...any help will be really appreciated..
#include "bsp.h"
#include "mrfi.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "nwk_frame.h"
#include "nwk.h"
#include "msp430x22x4.h"
#include "vlo_rand.h"
#define MESSAGE_LENGTH 9
void TXString( char* string, int length );
void MCU_Init(void);
void transmitData(int addr, signed char rssi, char msg[MESSAGE_LENGTH] );
void transmitDataString(char addr[4],char rssi[3], char msg[MESSAGE_LENGTH]);
void createRandomAddress();
//data for terminal output
const char splash[] = {"\r\n--------------------------------------------------\r\n ****\r\n **** eZ430-RF2500\r\n ******o**** Temperature Sensor Network\r\n********_///_**** Copyright 2007\r\n ******/_//_/***** Texas Instruments Incorporated\r\n ** ***(__/***** All rights reserved.\r\n ********* Version 1.02\r\n *****\r\n ***\r\n--------------------------------------------------\r\n"};
__no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set randomly
// reserve space for the maximum possible peer Link IDs
static linkID_t sLID[NUM_CONNECTIONS];
static uint8_t sNumCurrentPeers;
// callback handler
static uint8_t sCB(linkID_t);
// work loop semaphores
static uint8_t sPeerFrameSem;
static uint8_t sJoinSem;
static uint8_t sSelfMeasureSem;
// mode data verbose = default, deg F = default
char verboseMode = 1;
char degCMode = 0;
void main (void)
{
addr_t lAddr;
bspIState_t intState;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
// delay loop to ensure proper startup before SimpliciTI increases DCO
// This is typically tailored to the power supply used, and in this case
// is overkill for safety due to wide distribution.
volatile int i;
for(i = 0; i < 0xFFFF; i++){}
}
if( CALBC1_8MHZ == 0xFF ) // Do not run if cal values are erased
{
volatile int i;
P1DIR |= 0x03;
BSP_TURN_ON_LED1();
BSP_TURN_OFF_LED2();
while(1)
{
for(i = 0; i < 0x5FFF; i++){}
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
BSP_Init();
if( Flash_Addr[0] == 0xFF &&
Flash_Addr[1] == 0xFF &&
Flash_Addr[2] == 0xFF &&
Flash_Addr[3] == 0xFF )
{
createRandomAddress(); // set Random device address at initial startup
}
lAddr.addr[0]=Flash_Addr[0];
lAddr.addr[1]=Flash_Addr[1];
lAddr.addr[2]=Flash_Addr[2];
lAddr.addr[3]=Flash_Addr[3];
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
MCU_Init();
//Transmit splash screen and network init notification
TXString( (char*)splash, sizeof splash);
TXString( "\r\nInitializing Network....", 26 );
SMPL_Init(sCB);
// network initialized
TXString( "Done\r\n", 6);
// main work loop
while (1)
{
// Wait for the Join semaphore to be set by the receipt of a Join frame from a
// device that supports and End Device.
if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS))
{
// listen for a new connection
SMPL_LinkListen(&sLID[sNumCurrentPeers]);
sNumCurrentPeers++;
BSP_ENTER_CRITICAL_SECTION(intState);
if (sJoinSem)
{
sJoinSem--;
}
BSP_EXIT_CRITICAL_SECTION(intState);
}
// if it is time to measure our own temperature...
if(sSelfMeasureSem)
{
sSelfMeasureSem = 0;
}
// Have we received a frame on one of the ED connections?
// No critical section -- it doesn't really matter much if we miss a poll
if (sPeerFrameSem)
{
//uint8_t msg[MAX_APP_PAYLOAD], len, i;
uint8_t msg[ MESSAGE_LENGTH], len, i;
// process all frames waiting
for (i=0; i<sNumCurrentPeers; ++i)
{
if (SMPL_Receive(sLID[i], msg, &len) == SMPL_SUCCESS)
{
ioctlRadioSiginfo_t sigInfo;
sigInfo.lid = sLID[i];
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SIGINFO, (void *)&sigInfo);
transmitData( i, (signed char)sigInfo.sigInfo[0], (char*)msg );
BSP_TOGGLE_LED2();
BSP_ENTER_CRITICAL_SECTION(intState);
sPeerFrameSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}
}
}
}
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void createRandomAddress()
{
unsigned int rand, rand2;
do
{
rand = TI_getRandomIntegerFromVLO(); // first byte can not be 0x00 of 0xFF
}
while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
rand2 = TI_getRandomIntegerFromVLO();
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator
FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
Flash_Addr[0]=(rand>>8) & 0xFF;
Flash_Addr[1]=rand & 0xFF;
Flash_Addr[2]=(rand2>>8) & 0xFF;
Flash_Addr[3]=rand2 & 0xFF;
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void transmitData(int addr, signed char rssi, char msg[MESSAGE_LENGTH] )
{
char addrString[4];
char rssiString[3];
volatile signed int rssi_int;
addrString[0] = '0';
addrString[1] = '0';
addrString[2] = '0'+(((addr+1)/10)%10);
addrString[3] = '0'+((addr+1)%10);
rssi_int = (signed int) rssi;
rssi_int = rssi_int+128;
rssi_int = (rssi_int*100)/256;
rssiString[0] = '0'+(rssi_int%10);
rssiString[1] = '0'+((rssi_int/10)%10);
rssiString[2] = '0'+((rssi_int/100)%10);
transmitDataString( addrString, rssiString, msg );
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void transmitDataString(char addr[4],char rssi[3], char msg[MESSAGE_LENGTH] )
{
char output_short[] = {"\r\n$ADDR,XXXXX,XXXXX,XXXXX,XXXXX,XXX,RSI,N#"};
uint16_t temp_x = msg[0] + (msg[1]<<8);
uint16_t temp_y = msg[2] + (msg[3]<<8);
uint16_t temp_z = msg[4] + (msg[5]<<8);
uint16_t GMI_sensor = msg[6] + (msg[7]<<8);
uint8_t hall_sensor = msg[8];
// addr
output_short[3] = addr[0];
output_short[4] = addr[1];
output_short[5] = addr[2];
output_short[6] = addr[3];
// x-coordinate
output_short[12] = '0'+ (temp_x%10);
output_short[11] = '0'+ ((temp_x/10)%10);
output_short[10] = '0'+ ((temp_x/100)%10);
output_short[9] = '0'+ ((temp_x/1000)%10);
output_short[8] = '0'+ ((temp_x/10000)%10);
// y-coordinate
output_short[18] = '0'+ (temp_y%10);
output_short[17] = '0'+ ((temp_y/10)%10);
output_short[16] = '0'+ ((temp_y/100)%10);
output_short[15] = '0'+ ((temp_y/1000)%10);
output_short[14] = '0'+ ((temp_y/10000)%10);
// z-coordinate
output_short[24] = '0'+ (temp_z%10);
output_short[23] = '0'+ ((temp_z/10)%10);
output_short[22] = '0'+ ((temp_z/100)%10);
output_short[21] = '0'+ ((temp_z/1000)%10);
output_short[20] = '0'+ ((temp_z/10000)%10);
// GMI sensor
output_short[30] = '0'+ (GMI_sensor%10);
output_short[29] = '0'+ ((GMI_sensor/10)%10);
output_short[28] ='0'+ ((GMI_sensor/100)%10);
output_short[27] ='0'+ ((GMI_sensor/1000)%10);
output_short[26] ='0'+ ((GMI_sensor/10000)%10);
// hall sensor
output_short[34] ='0'+ (hall_sensor%10);
output_short[33] ='0'+ ((hall_sensor/10)%10);
output_short[32] ='0'+ ((hall_sensor/100)%10);
output_short[36] = rssi[2];
output_short[37] = rssi[1];
output_short[38] = rssi[0];
TXString(output_short, sizeof output_short);
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void TXString( char* string, int length )
{
int pointer;
for( pointer = 0; pointer < length; pointer++)
{
volatile int i;
UCA0TXBUF = string[pointer];
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
}
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void MCU_Init()
{
BCSCTL1 = CALBC1_8MHZ; // Set DCO
DCOCTL = CALDCO_8MHZ;
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 12000; // ~1 second
TACTL = TASSEL_1 + MC_1; // ACLK, upmode
P3SEL |= 0x30; // P3.4,5 = USCI_A0 TXD/RXD
UCA0CTL1 = UCSSEL_2; // SMCLK
UCA0BR0 = 0x41; // 9600 from 8Mhz
UCA0BR1 = 0x3;
UCA0MCTL = UCBRS_2;
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
__enable_interrupt();
}
/*------------------------------------------------------------------------------
* Runs in ISR context. Reading the frame should be done in the
* application thread not in the ISR thread.
------------------------------------------------------------------------------*/
static uint8_t sCB(linkID_t lid)
{
if (lid)
{
sPeerFrameSem++;
}
else
{
sJoinSem++;
}
// leave frame to be read by application.
return 0;
}
/*------------------------------------------------------------------------------
* ADC10 interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}
/*------------------------------------------------------------------------------
* Timer A0 interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
sSelfMeasureSem = 1;
}
/*------------------------------------------------------------------------------
* USCIA interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
char rx = UCA0RXBUF;
if ( rx == 'V' || rx == 'v' )
{
verboseMode = 1;
}
else if ( rx == 'M' || rx == 'm' )
{
verboseMode = 0;
}
else if ( rx == 'F' || rx == 'f' )
{
degCMode = 0;
}
else if ( rx == 'C' || rx == 'c' )
{
degCMode = 1;
}
}
The added code are highlighted.....PLEASE HELP!
#include "bsp.h"
#include "mrfi.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "nwk_frame.h"
#include "nwk.h"
#include "msp430x22x4.h"
#include "vlo_rand.h"
#define MESSAGE_LENGTH 9
void TXString( char* string, int length );
void MCU_Init(void);
void transmitData(int addr, signed char rssi, char msg[MESSAGE_LENGTH] );
void transmitDataString(char addr[4],char rssi[3], char msg[MESSAGE_LENGTH]);
void createRandomAddress();
//data for terminal output
const char splash[] = {"\r\n--------------------------------------------------\r\n ****\r\n **** eZ430-RF2500\r\n ******o**** Temperature Sensor Network\r\n********_///_**** Copyright 2007\r\n ******/_//_/***** Texas Instruments Incorporated\r\n ** ***(__/***** All rights reserved.\r\n ********* Version 1.02\r\n *****\r\n ***\r\n--------------------------------------------------\r\n"};
__no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set randomly
// reserve space for the maximum possible peer Link IDs
static linkID_t sLID[NUM_CONNECTIONS];
static uint8_t sNumCurrentPeers;
// callback handler
static uint8_t sCB(linkID_t);
// work loop semaphores
static uint8_t sPeerFrameSem;
static uint8_t sJoinSem;
static uint8_t sSelfMeasureSem;
// mode data verbose = default, deg F = default
char verboseMode = 1;
char degCMode = 0;
void main (void)
{
addr_t lAddr;
bspIState_t intState;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
// delay loop to ensure proper startup before SimpliciTI increases DCO
// This is typically tailored to the power supply used, and in this case
// is overkill for safety due to wide distribution.
volatile int i;
for(i = 0; i < 0xFFFF; i++){}
}
if( CALBC1_8MHZ == 0xFF ) // Do not run if cal values are erased
{
volatile int i;
P1DIR |= 0x03;
BSP_TURN_ON_LED1();
BSP_TURN_OFF_LED2();
while(1)
{
for(i = 0; i < 0x5FFF; i++){}
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
BSP_Init();
if( Flash_Addr[0] == 0xFF &&
Flash_Addr[1] == 0xFF &&
Flash_Addr[2] == 0xFF &&
Flash_Addr[3] == 0xFF )
{
createRandomAddress(); // set Random device address at initial startup
}
lAddr.addr[0]=Flash_Addr[0];
lAddr.addr[1]=Flash_Addr[1];
lAddr.addr[2]=Flash_Addr[2];
lAddr.addr[3]=Flash_Addr[3];
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
MCU_Init();
//Transmit splash screen and network init notification
TXString( (char*)splash, sizeof splash);
TXString( "\r\nInitializing Network....", 26 );
SMPL_Init(sCB);
// network initialized
TXString( "Done\r\n", 6);
// main work loop
while (1)
{
// Wait for the Join semaphore to be set by the receipt of a Join frame from a
// device that supports and End Device.
if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS))
{
// listen for a new connection
SMPL_LinkListen(&sLID[sNumCurrentPeers]);
sNumCurrentPeers++;
BSP_ENTER_CRITICAL_SECTION(intState);
if (sJoinSem)
{
sJoinSem--;
}
BSP_EXIT_CRITICAL_SECTION(intState);
}
// if it is time to measure our own temperature...
if(sSelfMeasureSem)
{
sSelfMeasureSem = 0;
}
// Have we received a frame on one of the ED connections?
// No critical section -- it doesn't really matter much if we miss a poll
if (sPeerFrameSem)
{
//uint8_t msg[MAX_APP_PAYLOAD], len, i;
uint8_t msg[ MESSAGE_LENGTH], len, i;
// process all frames waiting
for (i=0; i<sNumCurrentPeers; ++i)
{
if (SMPL_Receive(sLID[i], msg, &len) == SMPL_SUCCESS)
{
ioctlRadioSiginfo_t sigInfo;
sigInfo.lid = sLID[i];
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SIGINFO, (void *)&sigInfo);
transmitData( i, (signed char)sigInfo.sigInfo[0], (char*)msg );
BSP_TOGGLE_LED2();
BSP_ENTER_CRITICAL_SECTION(intState);
sPeerFrameSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}
}
}
}
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void createRandomAddress()
{
unsigned int rand, rand2;
do
{
rand = TI_getRandomIntegerFromVLO(); // first byte can not be 0x00 of 0xFF
}
while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
rand2 = TI_getRandomIntegerFromVLO();
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator
FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
Flash_Addr[0]=(rand>>8) & 0xFF;
Flash_Addr[1]=rand & 0xFF;
Flash_Addr[2]=(rand2>>8) & 0xFF;
Flash_Addr[3]=rand2 & 0xFF;
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void transmitData(int addr, signed char rssi, char msg[MESSAGE_LENGTH] )
{
char addrString[4];
char rssiString[3];
volatile signed int rssi_int;
addrString[0] = '0';
addrString[1] = '0';
addrString[2] = '0'+(((addr+1)/10)%10);
addrString[3] = '0'+((addr+1)%10);
rssi_int = (signed int) rssi;
rssi_int = rssi_int+128;
rssi_int = (rssi_int*100)/256;
rssiString[0] = '0'+(rssi_int%10);
rssiString[1] = '0'+((rssi_int/10)%10);
rssiString[2] = '0'+((rssi_int/100)%10);
transmitDataString( addrString, rssiString, msg );
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void transmitDataString(char addr[4],char rssi[3], char msg[MESSAGE_LENGTH] )
{
char output_short[] = {"\r\n$ADDR,XXXXX,XXXXX,XXXXX,XXXXX,XXX,RSI,N#"};
uint16_t temp_x = msg[0] + (msg[1]<<8);
uint16_t temp_y = msg[2] + (msg[3]<<8);
uint16_t temp_z = msg[4] + (msg[5]<<8);
uint16_t GMI_sensor = msg[6] + (msg[7]<<8);
uint8_t hall_sensor = msg[8];
// addr
output_short[3] = addr[0];
output_short[4] = addr[1];
output_short[5] = addr[2];
output_short[6] = addr[3];
// x-coordinate
output_short[12] = '0'+ (temp_x%10);
output_short[11] = '0'+ ((temp_x/10)%10);
output_short[10] = '0'+ ((temp_x/100)%10);
output_short[9] = '0'+ ((temp_x/1000)%10);
output_short[8] = '0'+ ((temp_x/10000)%10);
// y-coordinate
output_short[18] = '0'+ (temp_y%10);
output_short[17] = '0'+ ((temp_y/10)%10);
output_short[16] = '0'+ ((temp_y/100)%10);
output_short[15] = '0'+ ((temp_y/1000)%10);
output_short[14] = '0'+ ((temp_y/10000)%10);
// z-coordinate
output_short[24] = '0'+ (temp_z%10);
output_short[23] = '0'+ ((temp_z/10)%10);
output_short[22] = '0'+ ((temp_z/100)%10);
output_short[21] = '0'+ ((temp_z/1000)%10);
output_short[20] = '0'+ ((temp_z/10000)%10);
// GMI sensor
output_short[30] = '0'+ (GMI_sensor%10);
output_short[29] = '0'+ ((GMI_sensor/10)%10);
output_short[28] ='0'+ ((GMI_sensor/100)%10);
output_short[27] ='0'+ ((GMI_sensor/1000)%10);
output_short[26] ='0'+ ((GMI_sensor/10000)%10);
// hall sensor
output_short[34] ='0'+ (hall_sensor%10);
output_short[33] ='0'+ ((hall_sensor/10)%10);
output_short[32] ='0'+ ((hall_sensor/100)%10);
output_short[36] = rssi[2];
output_short[37] = rssi[1];
output_short[38] = rssi[0];
TXString(output_short, sizeof output_short);
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void TXString( char* string, int length )
{
int pointer;
for( pointer = 0; pointer < length; pointer++)
{
volatile int i;
UCA0TXBUF = string[pointer];
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
}
}
/*------------------------------------------------------------------------------
*
------------------------------------------------------------------------------*/
void MCU_Init()
{
BCSCTL1 = CALBC1_8MHZ; // Set DCO
DCOCTL = CALDCO_8MHZ;
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 12000; // ~1 second
TACTL = TASSEL_1 + MC_1; // ACLK, upmode
P3SEL |= 0x30; // P3.4,5 = USCI_A0 TXD/RXD
UCA0CTL1 = UCSSEL_2; // SMCLK
UCA0BR0 = 0x41; // 9600 from 8Mhz
UCA0BR1 = 0x3;
UCA0MCTL = UCBRS_2;
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
__enable_interrupt();
}
/*------------------------------------------------------------------------------
* Runs in ISR context. Reading the frame should be done in the
* application thread not in the ISR thread.
------------------------------------------------------------------------------*/
static uint8_t sCB(linkID_t lid)
{
if (lid)
{
sPeerFrameSem++;
}
else
{
sJoinSem++;
}
// leave frame to be read by application.
return 0;
}
/*------------------------------------------------------------------------------
* ADC10 interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}
/*------------------------------------------------------------------------------
* Timer A0 interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
sSelfMeasureSem = 1;
}
/*------------------------------------------------------------------------------
* USCIA interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
char rx = UCA0RXBUF;
if ( rx == 'V' || rx == 'v' )
{
verboseMode = 1;
}
else if ( rx == 'M' || rx == 'm' )
{
verboseMode = 0;
}
else if ( rx == 'F' || rx == 'f' )
{
degCMode = 0;
}
else if ( rx == 'C' || rx == 'c' )
{
degCMode = 1;
}
}
If I look at the eZ430-RF2500 schematics in the eZ430-RF2500 Development Tool User's Guide (SLAU227) on page 18, the USCI_B interface is not only available on the test points on the side of the board (P15 through P18), but also are connected to the CC2500 device.
Therefore I would think there is likely conflict between the CC2500 and your external device.
Have you already resolved this with possibility a different signal assignment?
Thanks Brandon, I really appreciate your help.
My board is kinda burnt..it does not seems to be working....ordering a new one now...so not much can be tested on it now...
For my project I have to use the SPI interface, I am just wondering if there is a way to disable the CC2500 using the SPI lines (the USCI B module). I am thinking that I use the same SPI lines (the USCI B module) connect to my PNI sensor, and get the data then Renable the CC2500 for wireless transmission......
disable
the CC2500 for wireless transmission then get the data (using the same
SPI lines) from the sensor...then enable the CC2500 for wireless
transmission...disable the CC2500 for wireless transmission...get the
data (using the same SPI lines) from the sensor...etc....
Also, there is
also the USCI A module ( P3.4 UCA 0SIMO , P3.5 UCA 0SOMI and P3.0 / UCA
0CLK). But the P3.0 is also routed to the CC2500. If I use USCI A
module, do I still need to disable the CC2500 for wireless
transmission, or both My sensor SPI and the wireless can share the
clock.
thanks everyboday,
zita
Also, we can pretty much only access the 18 pins on the target board and the 6 pins on the battery board...unless we have really good soldering skill. So if we have to use the (SIMO and SOMI and clk) SPI interface AND the wireless transmission, then it seems USC module A and module are our only option...but P3.0 to P3.3 are routed to C2500
Thanks everybody,
zita
zita wong said:For my project I have to use the SPI interface, I am just wondering if there is a way to disable the CC2500 using the SPI lines (the USCI B module). I am thinking that I use the same SPI lines (the USCI B module) connect to my PNI sensor, and get the data then Renable the CC2500 for wireless transmission......
disable the CC2500 for wireless transmission then get the data (using the same SPI lines) from the sensor...then enable the CC2500 for wireless transmission...disable the CC2500 for wireless transmission...get the data (using the same SPI lines) from the sensor...etc....
While this may be possible, I think it would be a rather difficult thing to manage as it would involve quite a bit of change of the software to manage a shared interface between to completely separate software module entities. Again, not impossible, but certainly would take a lot of consideration.
zita wong said:
Also, there is also the USCI A module ( P3.4 UCA 0SIMO , P3.5 UCA 0SOMI and P3.0 / UCA 0CLK). But the P3.0 is also routed to the CC2500. If I use USCI A module, do I still need to disable the CC2500 for wireless transmission, or both My sensor SPI and the wireless can share the clock.
Again, I don't think you can reasonably share the P3.0 (UCB0STE) signal which is going to the CC2500 radio and use it as a clock for your own SPI interface (ie. as UCA0CLK).
There are other signals from the MSP430F2274 to the test points on the RF2500T board. I might suggest that you use these signals as General Purpose I/O and emulate a SPI interface by toggling these I/Os with some software routines to generate the SPI signaling and capture of data. The other USCI interface is sent back to the eZ430 USB board as a UART.
Hi, Zita!
See this demo programs.
===================
///////////////// SPI Example -1 ///////////////////
//
// msp430x22x4
// -----------------
// | |
// SIMO <--|P3.1 |
// SOMI -->|P3.2 |
// CLC <--|P3.3 P4.2|--> LAMP
//
////////////////////////////////////////////////////////
#include <msp430x22x4.h>
void SPI_Init(char debug)
{
// P3 pins
P3DIR |= BIT1 + BIT3; // P3.1, P3.3 - output
P3SEL |= BIT1 + BIT2 + BIT3; // P3.1, P3.2, P3.3 - for SPI
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0CTL0 = UCSYNC + UCMST + UCMSB + UCCKPH;
UCB0BR0 = 2; // divider = 1/2
UCB0BR1 = 0;
if (debug) UCB0STAT |= UCLISTEN; // for debug only!
UCB0CTL1 &= ~UCSWRST;
}
//==================================================
// Read and write simultaneously !
// If you need read only, send any msg as dummy
char SPI_IO_Byte (char msg)
{
UCB0TXBUF = msg;
while (!(IFG2 & UCB0RXIFG));
IFG2 &= ~UCB0RXIFG;
return UCB0RXBUF;
}
//==================================================
void Pause(int time)
{
while (time--);
}
//==================================================
#define LAMP BIT2
char tst_out, tst_in;
int main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
// SPI_Init call once !
// 0 - for working, 1 - for debug
SPI_Init(1);
P4DIR |= LAMP;
_BIS_SR(GIE);
while (1)
{
Pause(10000);
tst_out++;
tst_in = SPI_IO_Byte(tst_out);
if (tst_in==tst_out)
P4OUT ^= LAMP; // ok
else
P4OUT |= LAMP; // error
}
}
===================
///////////////// SPI Example - 2 ///////////////////
//
// msp430x22x4
// -----------------
// | |
// SIMO <--|P3.1 |
// SOMI -->|P3.2 |
// CLC <--|P3.3 P4.2|--> LAMP
//
////////////////////////////////////////////////////////
#include <msp430x22x4.h>
void SPI_Init(char debug)
{
// P3 pins
P3DIR |= BIT1 + BIT3; // P3.1, P3.3 - output
P3SEL |= BIT1 + BIT2 + BIT3; // P3.1, P3.2, P3.3 - for SPI
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0CTL0 = UCSYNC + UCMST + UCMSB + UCCKPH;
UCB0BR0 = 2; // divider = 1/2
UCB0BR1 = 0;
if (debug) UCB0STAT |= UCLISTEN; // for debug only!
UCB0CTL1 &= ~UCSWRST;
}
//==================================================
// Read and write simultaneously !
// If you need read only, send any msg as dummy
int SPI_IO_Word (int msg)
{
int result;
UCB0TXBUF = msg / 0x100; // first = high
while (!(IFG2 & UCB0TXIFG)); // check TX flag!
UCB0TXBUF = msg % 0x100; // second = low
while (!(IFG2 & UCB0RXIFG)); // check RX flag!
result = UCB0RXBUF; // high
IFG2 &= ~UCB0RXIFG;
while (!(IFG2 & UCB0RXIFG)); // check RX flag!
IFG2 &= ~UCB0RXIFG;
result = (result << 8) + UCB0RXBUF; // 256*high + low
return result;
}
//==================================================
void Pause(int time)
{
while (time--);
}
//==================================================
#define LAMP BIT2
int tst_out, tst_in;
int main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
// SPI_Init call once !
// 0 - for working, 1 - for debug
SPI_Init(1);
P4DIR |= LAMP;
_BIS_SR(GIE);
while (1)
{
Pause(5000);
tst_out++;
tst_in = SPI_IO_Word(tst_out);
if (tst_in==tst_out)
P4OUT ^= LAMP; // ok
else
P4OUT |= LAMP; // error
}
}
hi every body
"Zita " could you please send to me the final code you used with the Micromag to and MSP430
thanks a lot
Hi everyone,
I am also interested in having a look at the final code. Can Zita or anybody have done it put the code in here please? I need to add a pressure sensor with analog output to ez430-RF2500-SEH.
Kindest regards,
Ali
here is my email;
ae_zt@yahoo.com
I am trying to make the code as well. If I will make it, I will put it in here
Thanks
**Attention** This is a public forum