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.

RF2500: about the callback and the SMPL_Receive...

Other Parts Discussed in Thread: SIMPLICITI, CC2500, MSP430F2274, TUSB3410

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

 

  • Hi Arceles

    Sounds like you are pretty close as you are able to receive from the AP if the button is pushed continuously, so without looking to much on you code I believe you are experiencing some timing issues. Since the ED does not know when you will push the button on the AP side, you will need to have the radio in RX when the ED is not tramsmitting the temperature. The status of the radio at all times can be read in the mrfiRadioState variable. If the ED is in MRFI_RADIO_STATE_RX when you push the button, the receive ISR will run and with this also running the callback function and setting enable = 1.  Once enable is set, the you can call SMPL_Receive  to retrieve the package.

    If you are not in MRFI_RADIO_STATE_RX when pushing the button, then you will not be able to receive.

    Hope this helps.

    Rgds,
    Kjetil

  • Well... I haven't tried that yet but... isn't there a way to enable an interrupt when an end device receives a frame from de acces point? life could be easier with that....

  • OK... I just don't know what to do...

    The only way to receive something in my end device is forcing... like this:

    //******************************************************************************Codigo envio de datos   
        if(send)
          {
            P4OUT |=0x08; //prendemos un led
            send=0;       //Y quitamos la bandera
            do
            { 
            while(SMPL_SUCCESS != SMPL_Send(sLID[0], "Hi", 2)); //intento de enviar algo
            i++;
            }
            while(i<60);
            i=0;
          }
         
        if(send==0)
          {
          P4OUT &= ~0x08; //apagamos el led
          }
    //******************************************************************************

    The message then arrives at the end device... but at the price of literally stopping the AP, but if I don't do it like this, I can't find a way to "sincronize" the moment of sending and receiving the message... (that's why I asked desesperately for some sort of Interrup)... now,even using some sort of "interrupt" like the callback, this doesn't work unless I force it... is there a way of not stopping so suddently the AP?... I just don't know what am I doing wrong... also if I connect another ed this one seems to receive the message too!!! (and this one also ackowledges the message...) how I can differentiate a message for only one ed? sorry for the bunch of questions... I still quite bit noob...

    thanks in advance.

     

    this is my code for the AP and the ED modified:

    ****************************************AP CODE

    #include "bsp.h" //Para dispositivos BSP (Board BSP Devices)
    #include "mrfi.h" //Minimal RF Interface (controla al CC2500 que traen los kits encargados del RF)
    #include "bsp_leds.h" //Leds contenidos dentro de la tablilla con el M430F2274
    #include "bsp_buttons.h" //botones contenidos dentro de la tablilla con el M430F2274
    #include "nwk_types.h"
    #include "nwk_api.h"   //Application Programming Interface (Segun la def... es una libreria que pueden usar varios programas y no solo este para comunicarse
    #include "nwk_frame.h"
    #include "nwk.h"       //Ti Simplicity Network Layer (NW... la k quien sabe de que sea)

    #include "msp430x22x4.h" //Definiciones para la familia MSP430x22x4 (nosotros usamos el MSP430F2274
    #include "vlo_rand.h"    //Su unica funcion... es obtener un valor aleatorio y devolverlo (en ADC y VLO)

    #define MESSAGE_LENGTH 6 //Definimos una constante llamada "MESSAGE_LENGHT" (Tamaño del mensaje, realmente solo es una constante) define el numero de datos a recivir (8bits)
    void TXString( char* string, int length ); //Funcion que no devuelve nada pero recibe un apuntador caracter 'string' (el asterisco lo cambia a apuntador) y un entero 'lenght'
    void MCU_Init(void); //funcion que ni devuelve ni recive nada, seguramente funciona como un inicializador.
    void transmitData(int addr, signed char rssi,  char msg[MESSAGE_LENGTH] ); //funcion que recibe entero 'addr', caracter con signo 'rssi', y cadena de caracteres msg[3]
    void transmitDataString(char addr[4],char rssi[3], char msg[MESSAGE_LENGTH]);// Idem, cadena de caracteres addr[4], cadena rssi[3], cadena msg[3]
    void createRandomAddress(); //funcion que no entrega nada, asi como esta tampoco recibe nada

    //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"}; //Pueden modificar a su antojo esto... lo unico que hace es desplegar el logo de texas instruments.

    __no_init volatile int tempOffset @ 0x10F4; // Temperature offset set at production , __no_init indica que las variables no se deben inicualizar al inicio de la ejecucion, el @ al parecer es una forma de asignar una direccion de apuntador
    __no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set randomly, idem, aqui la cadena empieza en el apuntador 0x10F0 y termina en 0x10F4 por cada caracter. (se traslapan?)

    // reserve space for the maximum possible peer Link IDs
    static linkID_t sLID[NUM_CONNECTIONS]; //static les reserva el espacio en memoria para la cadena sLID, es... una manera de direccionar los End Devices (0...1...2... y asi sucesivamente).
    static uint8_t  sNumCurrentPeers; //idem sNumCurrentPeers;

    // callback handler
    static uint8_t sCB(linkID_t); //ese uin8_t y casi todos los que tienen _t son tipos de datos hechos para el programa.

    // work loop semaphores
    static uint8_t sPeerFrameSem;
    static uint8_t sJoinSem;
    static uint8_t sSelfMeasureSem;

    // mode data verbose = default, deg F = default
    char send = 0;
    char degCMode = 0;
    char interrupt = 0;
    char enabletemp = 1;
    char enableADCch0 = 0; //Estas variables aparecen hasta abajo del codigo, sirven como banderas.
    int i=0x00; //Para enviar datos... una variable que almacene el conteo
    void main (void)
    {
      addr_t lAddr; //esto es como decir... int x donde int es addr_t y lAddr es x
      bspIState_t intState; //idem

      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT - Adios Watch Dog Timer
      {
      // 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., en otras palabras es un delay para que inicialize por completo el micro.
        volatile int i;
        for(i = 0; i < 0xFFFF; i++){}
      }
      if( CALBC1_8MHZ == 0xFF )                 // Do not run if cal values are erased, CALBC1_8MHZ es un registro
      {                                         // en la memoria flash que tiene los datos de calibracion del SMCLK...
        volatile int i;
        P1DIR |= 0x03;
        BSP_TURN_ON_LED1(); //prende led de la tarjetilla usb
        BSP_TURN_OFF_LED2(); //apaga led de la tarjetilla usb
        while(1)
        {
          for(i = 0; i < 0x5FFF; i++){}
          BSP_TOGGLE_LED2(); //prende... apaga... prende... apaga...
          BSP_TOGGLE_LED1();
        }
      }
       
      BSP_Init(); //LLamada a la funcion BSP_Init, muy probablemente inicialize la tarjetilla
     
      if( Flash_Addr[0] == 0xFF &&  //si Flash_addr del 1 al 4 esta lleno de FFs...
          Flash_Addr[1] == 0xFF &&
          Flash_Addr[2] == 0xFF &&
          Flash_Addr[3] == 0xFF )
      {
        createRandomAddress();                  // set Random device address at initial startup, ahora si hazlos aleatorios
      }
      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 ); //El numero tiene que ver con el tamaño de lo que se va a enviar.

      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)) //y aqui menciona que NUM_CONNECTIONS es igual a 7, si recibe una peticion de conectarse y aparte hay menos de 7 conectados encontes accede
        {
          // listen for a new connection
          SMPL_LinkListen(&sLID[sNumCurrentPeers]);
          sNumCurrentPeers++;
          BSP_ENTER_CRITICAL_SECTION(intState);
          if (sJoinSem)
          {
            sJoinSem--;
          }
          BSP_EXIT_CRITICAL_SECTION(intState);
        }
       
    //******************************************************************************Codigo envio de datos   
        if(send)
          {
            P4OUT |=0x08; //prendemos un led
            send=0;       //Y quitamos la bandera
            do
            { 
            while(SMPL_SUCCESS != SMPL_Send(sLID[0], "Hi", 2)); //intento de enviar algo
            i++;
            }
            while(i<60);
            i=0;
          }
         
        if(send==0)
          {
          P4OUT &= ~0x08; //apagamos el led
          }
    //******************************************************************************

       
        // if it is time to measure our own temperature...
        if(sSelfMeasureSem)
        {
          char msg [6];
          char addr[] = {"HUB0"};
          char rssi[] = {"000"};
          int res0, res1, res2;
          volatile long temp;
          int results[3];
          if (enabletemp)
          { 
          ADC10CTL1 = INCH_10 + ADC10DIV_4;     // Temp Sensor ADC10CLK/5 - Seleccion del ADC correspondiente al sensor de temperatura interno + clk dividido entre 5 para este adc
          ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR; // referencia VCC para Vref+ y VSS para Vref- (sin cableado) +
                                                                                 // Ciclos de reloj para 'sample and hold' provenientes del ADC10CLK +
                                                                                 // Generador de referencia encendido + Habilitar ADC + Habilitar Interrupciones del ADC +
                                                                                 // Redice la frecuencia de muestreo para reducir consumo de amperaje.
          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;                // De aqui obtenermos el resultado del adc, nota al respecto, literalmente tenemos que hacer todo esto si
                                                // Queremos una conversion, es decir, si cambiamos de canal, hay que hacer toooodo el rollo.
          ADC10CTL0 &= ~ENC;                    // Apagamos el ADC
          }
         
          if (enableADCch0)                    //Este es codigo agregado... sirve para medir un ADC de la tarjeta... VER EN LA HOJA DE DATOS LOS PINES YA QUE LOS NUMEROS NO CONCUERDAN CON EL PDF
          {
          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;
          }

          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;
         
          ADC10CTL1 = INCH_11;                  // AVcc/2 - Noten que el INCH_XX decide que canal usaremos... (Vcc-Vss)/2 + REF2_5 = un numero de 512 en 2.5v.
          ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V; //La ultima instruccion le dice al micro que tiene una referencia de 2.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
         
          // 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
          if(enabletemp)
          {
          temp = results[0];
          res0 = (((temp - 673) * 4230) / 1024);
             if( tempOffset != 0xFFFF )
              {
              res0 += tempOffset;
              }
          }
          if(enableADCch0)
          {
          temp = results[0];
          res0 = temp;
          }
         
          res2 = results[2];
         
          temp = results[1];
          res1 = (temp*25)/512; //Como arriba colocamos REF2_5V significa cuando tengamos 2.5v en el adc nos dara 512 o 0x200
                                //Ahora, en este caso, seleccionamos INCH_11 que es (VCC-VSS)/2 (3.6v provenientes de la alimentacion de la tarjeta se veran como 767 a lo mucho y el valor maximo es de 5v con 1023)
          msg[0] = res0&0xFF;   //parte baja de un numero de 16 bits, elimina la parte alta multiplicando por el 0xFF - EL ADC SOLO ES DE 10 BITS (1023 maximo numero)
          msg[1] = (res0>>8)&0xFF; //parte alta de un numero de 16 bits, elimina la parte baja corriendo los bits a la derecha y multiplicando por 0xFF
          msg[2] = res1; //50=5.0
          msg[3] = res2&0xFF;
          msg[4] = (res2>>8)&0xFF; 
          msg[5] = 0;
          transmitDataString(addr, rssi, msg );
          BSP_TOGGLE_LED1();
          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; //MAX_APP_PAYLOAD es igual a 10

          // 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 temp_string[] = {"XXXX"};
      char temp_string2[] = {"XXXX"};
      char temp_string3[] = {"X"};
      int temp2 = msg[3] + (msg[4]<<8);
      int temp = msg[0] + (msg[1]<<8);
      int ack = msg[5];
      /*
      if( !degCMode ) este codigo se usaba anteriormente con el unico proposito de transformar de celcius a farenheiht
      {
        temp = (((float)temp)*1.8)+320;
        temp_string[5] = 'F';
      }
      */
      if( temp < 0 ) //Se detecta si se debe poner un signo negativo
      {
        temp_string[0] = '-';
        temp = temp * -1;
      }
      else
      if( temp >= 0 ) //Aqui es para detectar si se tiene un 4to digito... por ejemplo en 1023 el 1 es el cuarto
      {
        temp_string[0] = '0'+((temp/1000)%10);
      }
      temp_string[3] = '0'+(temp%10); //ese %10 cambia de hexadecimal a decimal, permitiendo un despliegue de informacion
      temp_string[2] = '0'+((temp/10)%10); //en decimales, ademas de que aqui se divide cada parte del numero entre 10 para obtener
      temp_string[1] = '0'+((temp/100)%10); //cada caracter en unidades, decenas y centenas
     
      temp_string2[0] = '0'+((temp2/1000)%10);
      temp_string2[3] = '0'+(temp2%10); //ese %10 cambia de hexadecimal a decimal, permitiendo un despliegue de informacion
      temp_string2[2] = '0'+((temp2/10)%10); //en decimales, ademas de que aqui se divide cada parte del numero entre 10 para obtener
      temp_string2[1] = '0'+((temp2/100)%10); //cada caracter en unidades, decenas y centenas
     
      temp_string3[0] = '0'+ack; //realmente solo recibimos un 0 y un 1 por respuesta...
       
        char output_short[] = {"\r\n$ADDR XXXX V.C RSI MSG4 A"};
        //                                |grados de temperatura o adc channel 0, 4 digitos (posicion 8)
        //                                     |Voltaje de alimentacion del micro, 2 digitos (y un punto decimal) (posicion 13)
        //                                         |Cercania conforme al receptor, 3 digitos (posicion 17)
        //                                             |ADC Channel 1, 4 digitos (posicion 21)
        //                                                  |Acknowledge... del End Device, 1 digito (posicion 26)
        output_short[26] = temp_string3[0];
       
        output_short[21] = temp_string2[0];
        output_short[22] = temp_string2[1];
        output_short[23] = temp_string2[2];
        output_short[24] = temp_string2[3];
       
        output_short[17] = rssi[2];
        output_short[18] = rssi[1];
        output_short[19] = rssi[0];
           
        output_short[8] = temp_string[0];
        output_short[9] = temp_string[1];
        output_short[10] = temp_string[2];
        output_short[11] = temp_string[3];
      
        output_short[13] = '0'+(msg[2]/10)%10; //Aqui directamente pegan lo obtenido del adc, por eso los modulos y las sumas
        output_short[15] = '0'+(msg[2]%10);    //tranforman enteros y decimales y despues lo suman al '0'
       
        output_short[3] = addr[0];
        output_short[4] = addr[1];
        output_short[5] = addr[2];
        output_short[6] = addr[3];
       
        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, Literalmente... pon el micro en modo de 1 a 8 MHZ
      DCOCTL = CALDCO_8MHZ;                     // Ahora si, a 8 MHz
     
      BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO - oscilador interno de muy bajo consumo de poder, 12 KHz usualmente
      TACCTL0 = CCIE;                           // TACCR0 interrupt enabled - en castellano, interrupcion del Timer A habilitada
      //TACCR0 = 12000;                         // 12000 ~1 second - Aaaa... parece que encontre la velocidad, yup... es la velocidad, pero solo del maestro, los esclavos siguen igual de lentos
      TACCR0 = 1200;                            // Idem
      TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode - Fuente de relog para el timer A, ACLK (clock auxiliar) usualmente a 32 KHz + modo de conteo hacia rriba
                                                // Es decir hasta que llegue a TACCR0
      P3SEL |= 0x30;                            // P3.4,5 = USCI_A0 TXD/RXD Modo UART... o RS232 para nosotros.
      P4DIR |= 0x08;                            // Pin 4.3 salida
     
      UCA0CTL1 = UCSSEL_2;                      // SMCLK - UXAxCTL1 - Sub Main Clock como fuente para el RS232
      UCA0BR0 = 0x41;                           // 9600 from 8Mhz - (UCAxBR0 + UCAxBR1x256)=preescaler
      UCA0BR1 = 0x03;                           // entonces el baud rate queda 8MHz/Preescaler, que en este caso no puede ser mas de 9600 debido a una limitacion en la programacion del chip TUSB3410
                                                // cambiando los valores no se porque no funciono... el micro lanza valores extraños imposibles de leer
      UCA0MCTL = UCBRS_2;                     // control del UART- seleccion de segunda etapa de modulacion... quien sabe que demonios es eso.
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
      IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
      __enable_interrupt();                     // Y tan bonito que era el #use rs232(....
    }
    /*------------------------------------------------------------------------------
    * 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
    De aqui se pueden hacer algunas operaciones interesantes... ya que podemos recibir señales
    directamente del teclado y el micro las interpretara.
    ------------------------------------------------------------------------------*/
    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCI0RX_ISR(void)
    {
      char rx = UCA0RXBUF; //Recibimos de la computadora y lo almacenamos en un caracter
      if ( rx == 'S' || rx == 's' )
      {
        send = 1;
      }
      else if ( rx == 'I' || rx == 'i' )
      {
        interrupt = 1;
      }
      else if ( rx == 'C' || rx == 'c' )
      {
        degCMode = 1;
      }
      else if ( rx == 'T' || rx == 't' ) //Si te mayuscula o minuscula...
      {
        enabletemp = 1;
        enableADCch0 = 0;
      }
      else if ( rx == 'A' || rx == 'a' ) //Si te mayuscula o minuscula...
      {
        enabletemp = 0;
        enableADCch0 = 1;
      }
    }

    **************************************************************************ED CODE

    #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 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);

    //static volatile uint8_t  sPeerFrameSem;
    static          linkID_t linkID1;
    char ack=0;

    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 aqui esta la velocidad del esclavo
      TACCR0 = 1200;                            // Idem
      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_SUCCESS != SMPL_Init(sCB))
      {
        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[6], rcv[2]; //Nota, es importante cambiar este valor conforme los 'mensajes' que querramos enviar (el ultimo es un 'dato recibido del AP') + Variable para tratar de recivir dato del AP...
                               //Ya que si no, la comunicacion simplemente no se establece, cada mensaje es de 8 bits.
      uint8_t *z;     
     
      // 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)
      {
       
        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, "" );
       
        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.
        msg[5] = 0x00; //ultimo mensaje indica que se recibio el dato y fue procesado correctamente.
       
        //***************************************************************************************** codigo para recibir datos
       
        if(ack)
        {
          if (SMPL_SUCCESS == SMPL_Receive(linkID1, rcv, z))
          {
          P4OUT |=0x08; //prendemos un led
          msg[5] = 0x01; //ultimo mensaje indica que se recibio el dato y fue procesado correctamente.
          }           
        ack=0;
        }
       
       
       
        //*****************************************************************************************
       
        if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
        {
          BSP_TOGGLE_LED2();
        }
        else
        {
          BSP_TOGGLE_LED2();
          BSP_TOGGLE_LED1();
        }   
       
        SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);  //Prueba encendiendo el RX de un ENDPOINT
       
      }
    }

    //CALLBACK!!!!!!!!! esta cosa principalmente indica cuando un dato ha llegado. literalmente... es como hacer nuestra propia interrupcion.
    static uint8_t sCB(linkID_t lid)
    {
      SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);  //Prueba apagando el RX de un ENDPOINT
      if (lid == linkID1)
      {
        ack=1;
        BSP_TOGGLE_LED1();
        return 0;
      }

      return 1;
    }

    /*------------------------------------------------------------------------------
    * 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)
    }

     

  • Hello.

    Way, way too much code presented here to examine.

    I believe that the crux of your problem was highlighted by Kjetil. You do not need an interrupt -- it's already there. You need to have the receiver on when a device is to receive. It is that simple.The example turns off the receiver and puts the radio to sleep to save power. Presumably sensors are sampling the environemnt periodically and sending results to an always-on device before going back to sleep. You will get an interrupt (actually the callback invoked) when a frame is receved on a valid connection but obviously only if the radio's receiver is on.

    If you want the ED to receive as well you need to ensure that its receiver is on when the message is sent. This is a different scenario than the distributed example. One way to do this is to have the ED send a message and then remain with RX on until it gets a reply. The peer knows to reply when it gets the message from the device. SimpliciTI actually has native support for this. Look at the polling example application in the SimpliciTI distribution.

    SimpliciTI is not a beaconing protocol. You cannot synchronize time reliably. The callback feature that is supported does exactly what you want. It is invoked (if supplied) when the device receives a frame on a valid connection. But it does not solve your problem because you have not ensured that the radio's receiver is on. You need to have the receiver on when the frame is sent from the peer. Although it works, continually retrying from the sender side is not a good solution as you know. Better to have the peer that wants data to request it as I suggest above, or as the polling example supports.

    The example is for a periodic sensing device. If you want an actuating device or a device that also receives but is only powered sometimes you need a different scenario. SimpliciTI supports that in a couple of forms that I suggested above.

    Hope this helps.

    lfriedman

     

  • THANKS A LOT! YOU GUYS GIVE ME THE MAIN CLUE ABOUT WHY MY PROGRAM DIDN'T WORK AS I EXPECTED!!!!

    For those interested, if you are using the temp sensor demo... BE SURE TO PUT:

    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );
    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); 
    linkTo();

    BEFORE the linkTo(); FUNCTION!!! ALSO REMOVE THE LINE:

    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );

    (BECAUSE THIS ONE CAUSES THE CALLBACK TO ACT EXTRANGELY...)

    Now... I just have to find a workaround for the adresses problems...

  • Hello,

    I tried to do the same but it says that identifier "IOCTL_ACT_RADIO_RXON" is indefined. Do you know why????

    Thank you!

    Julie

  • Ok, it works know

  • Ok, it works know

  • It comes as undefined for me too... how did u solve the issue @ Julie Dethier