First of all... this is my first post but I've read it for a while. Thanks to you guys I was able to learn a bit about programing MSP430 microcontrollers.
But then, here is m question:
I was able to send a message with an AP to the ED by the "brute force method" (http://community.ti.com/forums/t/302.aspx) but... literally I have to keep the button pressed until the ED receives my message. I've been trying to found some information about the callbacks and how to handle them for correctly, this is to have some sort of "interruption" when a message is received and to process it as I want but no luck. could you guide me please through my search? or show me some example code please? I would be eternally grateful...
Here is my code if you want to see it (using the evaluation version of IAR kickstart that comes with the cd of ez430-rf2500) (thanks in advance)
#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"
char enable;
void linkTo(void);
void MCU_Init(void);
__no_init volatile int tempOffset @ 0x10F4; // Temperature offset set at production
__no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set randomly
void createRandomAddress();
// callback handler
static uint8_t sCB(linkID_t); //My.. My... vamos a ver si podemos hacer una bandera para cuando se recibe un dato
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_Init(sCB); //A lo mejor logra habilitar la 'interrupcion' para recepcion de mensajes
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 aqui esta la velocidad del esclavo
TACCR0 = 1200; // Idem
TACTL = TASSEL_1 + MC_1; // ACLK, upmode
P4DIR |= 0x08; // Pin 4.3 salida
// 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
}
void linkTo()
{
linkID_t linkID1;
uint8_t msg[5], rcv[2]; //Nota, es importante cambiar este valor conforme los 'mensajes' que querramos enviar + segunda Variable agregada para tratar de recivir dato del AP...
//Ya que si no, la comunicacion simplemente no se establece, cada mensaje es de 8 bits.
// keep trying to link...
uint8_t *z; //esta otra variable sirve para almacenar el tamaño de la cadena recivida... forzozamente tiene que tener el asterisco.
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)
{
volatile long temp;
int res0, res1, res2;
int results[3];
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
__bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts enabled
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );
//********************************************************************************************* Codigo para tratar de recivir un dato
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); //Prueba encendiendo el RX de un ENDPOINT
if(enable)
{
if (SMPL_SUCCESS == SMPL_Receive(linkID1, rcv, z)) //Se recibio un mensaje?
{
BSP_TOGGLE_LED1();
enable = 0;
}
}
//*********************************************************************************************
BSP_TOGGLE_LED2();
//****************************************************************************ADC de sensor de temperatura
/*
ADC10CTL1 = INCH_10 + ADC10DIV_4; // Temp Sensor ADC10CLK/5
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
for( res0 = 240; res0 > 0; res0-- ); // delay to allow reference to settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
results[0] = ADC10MEM;
ADC10CTL0 &= ~ENC;
*/
//****************************************************************************ADC ANALOG0
ADC10CTL1 = INCH_0; // Noten que el INCH_XX decide que canal usaremos... (en este caso el ANALOG0)
ADC10CTL0 = SREF_2 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE; //La primera instruccion le dice que tomaremos una referencia externa positiva y que la negativa sera Vss
for( res0 = 240; res0 > 0; res0-- ); // delay to allow reference to settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
results[0] = ADC10MEM;
ADC10CTL0 &= ~ENC;
//*****************************************************************************ADC de sensor de bateria
ADC10CTL1 = INCH_11; // AVcc/2
ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
for( res0 = 240; res0 > 0; res0-- ); // delay to allow reference to settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
results[1] = ADC10MEM;
ADC10CTL0 &= ~ENC;
ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power
//*****************************************************************************ADC ANALOG1
ADC10CTL1 = INCH_1; // Noten que el INCH_XX decide que canal usaremos... (en este caso el ANALOG1)
ADC10CTL0 = SREF_2 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE; //La primera instruccion le dice que tomaremos una referencia externa positiva y que la negativa sera Vss
for( res0 = 240; res0 > 0; res0-- ); // delay to allow reference to settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
results[2] = ADC10MEM;
ADC10CTL0 &= ~ENC;
// oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
// the temperature is transmitted as an integer where 32.1 = 321
// hence 4230 instead of 423
temp = results[0];
res0 = ((temp - 673) * 4230) / 1024;
if( tempOffset != 0xFFFF )
{
res0 += tempOffset;
}
/*message format, UB = upper Byte, LB = lower Byte
-------------------------------
|degC LB | degC UB | volt LB |
-------------------------------
0 1 2
*/
temp = results[1];
res1 = (temp*25)/512;
res2 = results[2];
msg[0] = res0&0xFF; //igual que en el Access Point, parte baja correspondiente a la temperatura
msg[1] = (res0>>8)&0xFF; //idem, parte alta.
msg[2] = res1;
msg[3] = res2&0xFF; //aqui agregamos un mensaje mas, que es un 255 realmente, esta es la parte baja
msg[4] = (res2>>8)&0xFF; //y aqui esta su respectiva parte alta.
if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
{
BSP_TOGGLE_LED2();
}
else
{
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
}
/*------------------------------------------------------------------------------
* 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 != 0)
{
P4OUT |=0x08; //prendemos un led
enable = 1;
}
else
{
P4OUT &= ~0x08; //apagamos el led
}
// 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)
{
__bic_SR_register_on_exit(LPM3_bits); // Clear LPM3 bit from 0(SR)
}