- Messaggi: 18
- Ringraziamenti ricevuti 0
×
MSP430, Microcontrollori 16 bit Ultra Low Power
eZ-430 Chronos !!
12 Anni 6 Mesi fa - 12 Anni 6 Mesi fa #6
da cardis
Risposta da cardis al topic Re: eZ-430 Chronos !!
Mi son dovuto fermare per cause di forza maggiore... Dovrei riprendere in mano il tutto la prossima settimana!
Ho studiato un pò in generale gli MSP430 da quel tutorial accademico della TI preso da qui
Visto la user's guide dei cc430, il datasheet del micro ( cc430f6137) e la struttura del codice dentro il chronos.
E qui nascono i problemini...
Scrivendo un codice contenente semplicemente una ISR, compatibilmente corretta, e caricandola sul chronos :
1) in quale parte della memoria verrebbe inserita? c'è bisogno di compilare tutto il sw del chronos ogni volta?
Ho avuto qualche difficoltà nel gestire i registri del core radio ( l'idea di sfruttare il parametro RSSI è ottima ) , ma magari mi sono informato male e devo solamente approfondire un pò la ricerca !!
L'obiettivo è far comunicare 2 Ch, usando un transceiver ( CC1111) come master, solo quando si trovano entro un certo raggio.
Ho studiato un pò in generale gli MSP430 da quel tutorial accademico della TI preso da qui
Visto la user's guide dei cc430, il datasheet del micro ( cc430f6137) e la struttura del codice dentro il chronos.
E qui nascono i problemini...
Scrivendo un codice contenente semplicemente una ISR, compatibilmente corretta, e caricandola sul chronos :
1) in quale parte della memoria verrebbe inserita? c'è bisogno di compilare tutto il sw del chronos ogni volta?
Ho avuto qualche difficoltà nel gestire i registri del core radio ( l'idea di sfruttare il parametro RSSI è ottima ) , ma magari mi sono informato male e devo solamente approfondire un pò la ricerca !!
L'obiettivo è far comunicare 2 Ch, usando un transceiver ( CC1111) come master, solo quando si trovano entro un certo raggio.
Ultima Modifica 12 Anni 6 Mesi fa da cardis.
Si prega Accedi o Crea un account a partecipare alla conversazione.
- cardis
- Autore della discussione
- New Member
Riduci
Di più
12 Anni 6 Mesi fa #7
da Mauro Laurenti
Rendering Error in layout Message/Item: array_keys(): Argument #1 ($array) must be of type array, null given. Please enable debug mode for more information.
Risposta da Mauro Laurenti al topic Re: eZ-430 Chronos !!
Rendering Error in layout Message/Item: array_keys(): Argument #1 ($array) must be of type array, null given. Please enable debug mode for more information.
Si prega Accedi o Crea un account a partecipare alla conversazione.
12 Anni 1 Mese fa #8
da cardis
Risposta da cardis al topic Re: eZ-430 Chronos !!
Tra incidenti vari sto riprendendo ora in mano la tesi...
Sto avendo delle difficoltà a programmare l'interfaccia radio!
Per facilitarmi il compito ho preso un esempio di codice dove si facevano comunicare tra loro 2 ch, ma fa uso di funzioni tratte da simpliciti...che non so quali registri vadano a modificare!!
Oltretutto ci sono dei passaggi logistici che non capisco...
Tipo:
Perchè deve aggiornare un indirizzo nella prima funzione? (simpliciti_link)
In teoria vorrei semplicemente far comunicare tra loro gli orologi solo in presenza di un terzo oggetto che trasmette sempre un segnale a una certa frequenza.
Poi far valutare il parametro RSSI...
Ogni suggerimento e ben accetto!!
Per ora mi dedico ad approfondire un po simpliciti in attesa di risvolti
Sto avendo delle difficoltà a programmare l'interfaccia radio!
Per facilitarmi il compito ho preso un esempio di codice dove si facevano comunicare tra loro 2 ch, ma fa uso di funzioni tratte da simpliciti...che non so quali registri vadano a modificare!!
Oltretutto ci sono dei passaggi logistici che non capisco...
Tipo:
Perchè deve aggiornare un indirizzo nella prima funzione? (simpliciti_link)
Attenzione: Spoiler!
/**********************************************************************************************
* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved.
*
* IMPORTANT: Your use of this Software is limited to those specific rights granted under
* the terms of a software license agreement between the user who downloaded the software,
* his/her employer (which must be your employer) and Texas Instruments Incorporated (the
* "License"). You may not use this Software unless you agree to abide by the terms of the
* License. The License limits your use, and you acknowledge, that the Software may not be
* modified, copied or distributed unless embedded on a Texas Instruments microcontroller
* or used solely and exclusively in conjunction with a Texas Instruments radio frequency
* transceiver, which is integrated into your product. Other than for the foregoing purpose,
* you may not use, reproduce, copy, prepare derivative works of, modify, distribute,
* perform, display or sell this Software and/or its documentation for any purpose.
*
* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS”
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE
* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY
* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST
* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY
* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*
* Should you have any questions regarding your right to use this Software,
* contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
// *************************************************************************************************
// Include section
#include "bsp.h"
#include "mrfi.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "simpliciti.h"
// *************************************************************************************************
// Defines section
#define TIMEOUT (10u)
// Conversion from msec to ACLK timer ticks
#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000)
// U16
typedef unsigned short u16;
// *************************************************************************************************
// Prototypes section
static uint8_t Link_Callback(linkID_t);
static uint8_t Listen_Callback(linkID_t);
// *************************************************************************************************
// Extern section
extern uint8_t sInit_done;
// SimpliciTI has no low power delay function, so we have to use ours
extern void Timer0_A4_Delay(u16 ticks);
// *************************************************************************************************
// Global Variable section
static linkID_t sLinkID1;
static linkID_t sLinkID2;
static volatile uint8_t sSemaphore = 0;
// *************************************************************************************************
// @fn simpliciti_link
// @brief Init hardware and try to link to access point.
// @param none
// @return unsigned char 0 = Could not link, timeout or external cancel.
// 1 = Linked successfully.
// *************************************************************************************************
unsigned char simpliciti_link(void)
{
uint8_t timeout;
addr_t lAddr;
uint8_t i;
uint8_t pwr;
// Configure timer
BSP_InitBoard();
// Change network address to value set in calling function
for (i = 0; i < NET_ADDR_SIZE; i++)
{
lAddr.addr = simpliciti_ed_address;
}
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
// Set flag
simpliciti_flag |= SIMPLICITI_STATUS_LINKING;
// Keep trying to join (a side effect of successful initialization) until
// successful. Toggle LEDS in AP to indicate that joining has not occurred.
timeout = 0;
while (SMPL_SUCCESS != SMPL_Init(0))
{
NWK_DELAY(1000);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Stop connecting after defined numbers of seconds (15)
if (timeout++ > TIMEOUT)
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
simpliciti_flag = SIMPLICITI_STATUS_ERROR;
return (0);
}
// Break when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
return (0);
}
}
// Set output power to +3.3dmB
pwr = IOCTL_LEVEL_2;
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr);
// Unconditional link to AP which is listening due to successful join.
timeout = 0;
while (SMPL_SUCCESS != SMPL_Link(&sLinkID1))
{
NWK_DELAY(1000);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Stop linking after timeout
if (timeout++ > TIMEOUT)
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
simpliciti_flag = SIMPLICITI_STATUS_ERROR;
return (0);
}
// Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
return (0);
}
}
simpliciti_flag |= SIMPLICITI_STATUS_LINKED;
return (1);
}
// *************************************************************************************************
// @fn simpliciti_2chronos_link
// @brief Init hardware and try to link to other eZ430-Chronos
// @param none
// @return unsigned char 0 = Could not link, timeout or external cancel.
// 1 = Linked successfully.
// *************************************************************************************************
unsigned char simpliciti_2chronos(void)
{
BSP_InitBoard();
uint8_t pwr;
addr_t lAddr;
uint8_t i;
uint8_t simpliciti_flag_aux;
// Change network address to value set in calling function
for (i = 0; i < NET_ADDR_SIZE; i++)
{
lAddr.addr = simpliciti_ed_address;
}
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
// Set flag
simpliciti_flag = SIMPLICITI_2CHRONOS_LINK;
while (1)
{
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
if (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LINK))
simpliciti_flag_aux = SIMPLICITI_2CHRONOS_LINK;
else if (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LISTEN))
simpliciti_flag_aux = SIMPLICITI_2CHRONOS_LISTEN;
// random function
switch (simpliciti_flag_aux)
{
case SIMPLICITI_2CHRONOS_LINK:
sInit_done = 0;
SMPL_Init(Link_Callback);
pwr = IOCTL_LEVEL_2;
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr);
do
{
if (SMPL_SUCCESS == SMPL_Link(&sLinkID2))
{
simpliciti_flag = SIMPLICITI_STATUS_LINKED;
simpliciti_flag |= SIMPLICITI_2CHRONOS_LINK;
return (1);
}
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
sInit_done = 0;
return (0);
}
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
} while (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LINK));
break;
case SIMPLICITI_2CHRONOS_LISTEN:
sInit_done = 0;
SMPL_Init(Listen_Callback);
pwr = IOCTL_LEVEL_2;
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr);
do
{
if (SMPL_SUCCESS == SMPL_LinkListen(&sLinkID2))
{
rf2chronos_send_sync();
return (1);
}
// Break when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
return (0);
}
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
} while (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LISTEN));
break;
}
}
}
// *************************************************************************************************
// @fn simpliciti_link
// @brief Init hardware and try to link to access point.
// @param none
// @return unsigned char 0 = Could not link, timeout or external cancel.
// 1 = Linked successfully.
// *************************************************************************************************
void simpliciti_control_other_watch(void)
{
// check what to send
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
// request the data
simpliciti_2chronos_get_data_callback();
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
simpliciti_data[0] = SYNC_2CHRONOS_CMD_DISCONNECT;
// with this flag we will get out of this loop and loop in rfsimpliciti.c
simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
}
SMPL_Send(sLinkID2, simpliciti_data, BM_SYNC_DATA_LENGTH);
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
NWK_DELAY(20);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);
// Put radio back to sleep
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
}
// *************************************************************************************************
// @fn simpliciti_receive_command_from_other_watch
// @brief Receive command from other watch and triggers action
// @param none
// @return none
// *************************************************************************************************
void simpliciti_receive_command_from_other_watch(void)
{
uint16_t i;
// Get radio ready. Wakes up in IDLE state.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
// Turn on RX. default is RX off.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
// to ensure that the device will be listening when the other watch tries to send a message
for (i = 15000; i > 1; i--)
{
// if it received any data from the other watch
if (sSemaphore)
{
// answer to received message
simpliciti_2chronos_get_data_callback();
// If this is a linker device and this is the last message, we have to
// overwrite the simpliciti_data[0] with the stop command for the other watch
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
simpliciti_data[0] = SYNC_2CHRONOS_CMD_DISCONNECT;
// with this flag we will get out of this loop and loop in rfsimpliciti.c
simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
}
// send twice since we don't receive ACK as confirmation
SMPL_Send(sLinkID2, simpliciti_data, BM_SYNC_DATA_LENGTH);
sSemaphore = 0;
}
// Watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
break;
}
}
// The next two lines are used to save energy
// Put radio to idle mode
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);
// Put radio back to SLEEP state
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
}
// *************************************************************************************************
// @fn Link_Callback
// @brief handle received frames.
// @param none linkID_t link identifier
// @return static uint8_t 0 = didn't receive one message
// 1 = the received message is in simpliciti_data
// *************************************************************************************************
static uint8_t Link_Callback(linkID_t port)
{
uint8_t len;
/* is the callback for the link ID we want to handle? */
if (port == sLinkID2)
{
/* yes. go get the frame. we know this call will succeed. */
if ((SMPL_SUCCESS == SMPL_Receive(sLinkID2, simpliciti_data, &len)) && len)
{
// call handle function
sSemaphore = 1;
simpliciti_2chronos_decode_data_callback();
return 1;
}
}
/* keep frame for later handling. */
return 0;
}
// *************************************************************************************************
// @fn simpliciti_main_tx_only
// @brief Get data through callback. Transfer data when external trigger is set.
// @param none
// @return none
// *************************************************************************************************
void simpliciti_main_tx_only(void)
{
while (1)
{
// Get end device data from callback function
simpliciti_get_ed_data_callback();
// Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA))
{
// Get radio ready. Wakes up in IDLE state.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
// Acceleration / button events packets are 4 bytes long
SMPL_SendOpt(sLinkID1, simpliciti_data, 4, SMPL_TXOPTION_NONE);
// Put radio back to SLEEP state
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA);
}
// Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
break;
}
}
}
// *************************************************************************************************
// @fn simpliciti_main_sync
// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply.
// Decode received host command and trigger action.
// @param none
// @return none
// *************************************************************************************************
void simpliciti_main_sync(void)
{
uint8_t len, i;
uint8_t ed_data[2];
while (1)
{
// Sleep 0.5sec between ready-to-receive packets
// SimpliciTI has no low power delay function, so we have to use ours
Timer0_A4_Delay(CONV_MS_TO_TICKS(500));
// Get radio ready. Radio wakes up in IDLE state.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
// Send 2 byte long ready-to-receive packet to stimulate host reply
ed_data[0] = SYNC_ED_TYPE_R2R;
ed_data[1] = 0xCB;
SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE);
// Wait shortly for host reply
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
NWK_DELAY(10);
// Check if a command packet was received
while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS)
{
// Decode received data
if (len > 0)
{
// Use callback function in application to decode data and react
simpliciti_sync_decode_ap_cmd_callback();
// Get reply data and send out reply packet burst (19 bytes each)
for (i = 0; i < simpliciti_reply_count; i++)
{
NWK_DELAY(10);
simpliciti_sync_get_data_callback(i);
SMPL_SendOpt(sLinkID1, simpliciti_data, BM_SYNC_DATA_LENGTH, SMPL_TXOPTION_NONE);
}
}
}
// Put radio back to sleep
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
break;
}
}
}
// *************************************************************************************************
// @fn reset_simpliciti
// @brief Reset flag enabling reconnection
// @param none
// @return none
// *************************************************************************************************
void reset_simpliciti(void)
{
sInit_done = 0;
}
// *************************************************************************************************
// @fn simpliciti_main_sync
// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply.
// Decode received host command and trigger action.
// @param none
// @return none
// *************************************************************************************************
static uint8_t Listen_Callback(linkID_t port)
{
uint8_t len;
/* is the callback for the link ID we want to handle? */
if (port == sLinkID2)
{
/* yes. go get the frame. we know this call will succeed. */
if ((SMPL_SUCCESS == SMPL_Receive(sLinkID2, simpliciti_data, &len)) && len)
{
simpliciti_2chronos_decode_data_callback();
return 1;
}
}
/* keep frame for later handling */
return 0;
}
void rf2chronos_send_sync(void)
{
// check what to send
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
// choose what data to send
simpliciti_data[0] = SYNC_2CHRONOS_CMD_DATA_SYNC;
while (simpliciti_data[0] != SYNC_2CHRONOS_CMD_ACK)
{
simpliciti_2chronos_get_data_callback();
SMPL_Send(sLinkID2, simpliciti_data, BM_SYNC_DATA_LENGTH);
NWK_DELAY(60);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Break when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
break;
}
}
// SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);
// Put radio back to sleep
// SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
simpliciti_flag = SIMPLICITI_STATUS_LINKED;
simpliciti_flag |= SIMPLICITI_2CHRONOS_LISTEN;
}
* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved.
*
* IMPORTANT: Your use of this Software is limited to those specific rights granted under
* the terms of a software license agreement between the user who downloaded the software,
* his/her employer (which must be your employer) and Texas Instruments Incorporated (the
* "License"). You may not use this Software unless you agree to abide by the terms of the
* License. The License limits your use, and you acknowledge, that the Software may not be
* modified, copied or distributed unless embedded on a Texas Instruments microcontroller
* or used solely and exclusively in conjunction with a Texas Instruments radio frequency
* transceiver, which is integrated into your product. Other than for the foregoing purpose,
* you may not use, reproduce, copy, prepare derivative works of, modify, distribute,
* perform, display or sell this Software and/or its documentation for any purpose.
*
* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS”
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE
* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY
* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST
* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY
* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*
* Should you have any questions regarding your right to use this Software,
* contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
// *************************************************************************************************
// Include section
#include "bsp.h"
#include "mrfi.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "simpliciti.h"
// *************************************************************************************************
// Defines section
#define TIMEOUT (10u)
// Conversion from msec to ACLK timer ticks
#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000)
// U16
typedef unsigned short u16;
// *************************************************************************************************
// Prototypes section
static uint8_t Link_Callback(linkID_t);
static uint8_t Listen_Callback(linkID_t);
// *************************************************************************************************
// Extern section
extern uint8_t sInit_done;
// SimpliciTI has no low power delay function, so we have to use ours
extern void Timer0_A4_Delay(u16 ticks);
// *************************************************************************************************
// Global Variable section
static linkID_t sLinkID1;
static linkID_t sLinkID2;
static volatile uint8_t sSemaphore = 0;
// *************************************************************************************************
// @fn simpliciti_link
// @brief Init hardware and try to link to access point.
// @param none
// @return unsigned char 0 = Could not link, timeout or external cancel.
// 1 = Linked successfully.
// *************************************************************************************************
unsigned char simpliciti_link(void)
{
uint8_t timeout;
addr_t lAddr;
uint8_t i;
uint8_t pwr;
// Configure timer
BSP_InitBoard();
// Change network address to value set in calling function
for (i = 0; i < NET_ADDR_SIZE; i++)
{
lAddr.addr = simpliciti_ed_address;
}
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
// Set flag
simpliciti_flag |= SIMPLICITI_STATUS_LINKING;
// Keep trying to join (a side effect of successful initialization) until
// successful. Toggle LEDS in AP to indicate that joining has not occurred.
timeout = 0;
while (SMPL_SUCCESS != SMPL_Init(0))
{
NWK_DELAY(1000);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Stop connecting after defined numbers of seconds (15)
if (timeout++ > TIMEOUT)
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
simpliciti_flag = SIMPLICITI_STATUS_ERROR;
return (0);
}
// Break when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
return (0);
}
}
// Set output power to +3.3dmB
pwr = IOCTL_LEVEL_2;
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr);
// Unconditional link to AP which is listening due to successful join.
timeout = 0;
while (SMPL_SUCCESS != SMPL_Link(&sLinkID1))
{
NWK_DELAY(1000);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Stop linking after timeout
if (timeout++ > TIMEOUT)
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
simpliciti_flag = SIMPLICITI_STATUS_ERROR;
return (0);
}
// Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
return (0);
}
}
simpliciti_flag |= SIMPLICITI_STATUS_LINKED;
return (1);
}
// *************************************************************************************************
// @fn simpliciti_2chronos_link
// @brief Init hardware and try to link to other eZ430-Chronos
// @param none
// @return unsigned char 0 = Could not link, timeout or external cancel.
// 1 = Linked successfully.
// *************************************************************************************************
unsigned char simpliciti_2chronos(void)
{
BSP_InitBoard();
uint8_t pwr;
addr_t lAddr;
uint8_t i;
uint8_t simpliciti_flag_aux;
// Change network address to value set in calling function
for (i = 0; i < NET_ADDR_SIZE; i++)
{
lAddr.addr = simpliciti_ed_address;
}
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
// Set flag
simpliciti_flag = SIMPLICITI_2CHRONOS_LINK;
while (1)
{
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
if (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LINK))
simpliciti_flag_aux = SIMPLICITI_2CHRONOS_LINK;
else if (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LISTEN))
simpliciti_flag_aux = SIMPLICITI_2CHRONOS_LISTEN;
// random function
switch (simpliciti_flag_aux)
{
case SIMPLICITI_2CHRONOS_LINK:
sInit_done = 0;
SMPL_Init(Link_Callback);
pwr = IOCTL_LEVEL_2;
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr);
do
{
if (SMPL_SUCCESS == SMPL_Link(&sLinkID2))
{
simpliciti_flag = SIMPLICITI_STATUS_LINKED;
simpliciti_flag |= SIMPLICITI_2CHRONOS_LINK;
return (1);
}
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
sInit_done = 0;
return (0);
}
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
} while (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LINK));
break;
case SIMPLICITI_2CHRONOS_LISTEN:
sInit_done = 0;
SMPL_Init(Listen_Callback);
pwr = IOCTL_LEVEL_2;
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr);
do
{
if (SMPL_SUCCESS == SMPL_LinkListen(&sLinkID2))
{
rf2chronos_send_sync();
return (1);
}
// Break when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
return (0);
}
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
} while (getFlag(simpliciti_flag, SIMPLICITI_2CHRONOS_LISTEN));
break;
}
}
}
// *************************************************************************************************
// @fn simpliciti_link
// @brief Init hardware and try to link to access point.
// @param none
// @return unsigned char 0 = Could not link, timeout or external cancel.
// 1 = Linked successfully.
// *************************************************************************************************
void simpliciti_control_other_watch(void)
{
// check what to send
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
// request the data
simpliciti_2chronos_get_data_callback();
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
simpliciti_data[0] = SYNC_2CHRONOS_CMD_DISCONNECT;
// with this flag we will get out of this loop and loop in rfsimpliciti.c
simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
}
SMPL_Send(sLinkID2, simpliciti_data, BM_SYNC_DATA_LENGTH);
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
NWK_DELAY(20);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);
// Put radio back to sleep
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
}
// *************************************************************************************************
// @fn simpliciti_receive_command_from_other_watch
// @brief Receive command from other watch and triggers action
// @param none
// @return none
// *************************************************************************************************
void simpliciti_receive_command_from_other_watch(void)
{
uint16_t i;
// Get radio ready. Wakes up in IDLE state.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
// Turn on RX. default is RX off.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
// to ensure that the device will be listening when the other watch tries to send a message
for (i = 15000; i > 1; i--)
{
// if it received any data from the other watch
if (sSemaphore)
{
// answer to received message
simpliciti_2chronos_get_data_callback();
// If this is a linker device and this is the last message, we have to
// overwrite the simpliciti_data[0] with the stop command for the other watch
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
simpliciti_data[0] = SYNC_2CHRONOS_CMD_DISCONNECT;
// with this flag we will get out of this loop and loop in rfsimpliciti.c
simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
}
// send twice since we don't receive ACK as confirmation
SMPL_Send(sLinkID2, simpliciti_data, BM_SYNC_DATA_LENGTH);
sSemaphore = 0;
}
// Watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
break;
}
}
// The next two lines are used to save energy
// Put radio to idle mode
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);
// Put radio back to SLEEP state
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
}
// *************************************************************************************************
// @fn Link_Callback
// @brief handle received frames.
// @param none linkID_t link identifier
// @return static uint8_t 0 = didn't receive one message
// 1 = the received message is in simpliciti_data
// *************************************************************************************************
static uint8_t Link_Callback(linkID_t port)
{
uint8_t len;
/* is the callback for the link ID we want to handle? */
if (port == sLinkID2)
{
/* yes. go get the frame. we know this call will succeed. */
if ((SMPL_SUCCESS == SMPL_Receive(sLinkID2, simpliciti_data, &len)) && len)
{
// call handle function
sSemaphore = 1;
simpliciti_2chronos_decode_data_callback();
return 1;
}
}
/* keep frame for later handling. */
return 0;
}
// *************************************************************************************************
// @fn simpliciti_main_tx_only
// @brief Get data through callback. Transfer data when external trigger is set.
// @param none
// @return none
// *************************************************************************************************
void simpliciti_main_tx_only(void)
{
while (1)
{
// Get end device data from callback function
simpliciti_get_ed_data_callback();
// Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA))
{
// Get radio ready. Wakes up in IDLE state.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
// Acceleration / button events packets are 4 bytes long
SMPL_SendOpt(sLinkID1, simpliciti_data, 4, SMPL_TXOPTION_NONE);
// Put radio back to SLEEP state
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA);
}
// Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
break;
}
}
}
// *************************************************************************************************
// @fn simpliciti_main_sync
// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply.
// Decode received host command and trigger action.
// @param none
// @return none
// *************************************************************************************************
void simpliciti_main_sync(void)
{
uint8_t len, i;
uint8_t ed_data[2];
while (1)
{
// Sleep 0.5sec between ready-to-receive packets
// SimpliciTI has no low power delay function, so we have to use ours
Timer0_A4_Delay(CONV_MS_TO_TICKS(500));
// Get radio ready. Radio wakes up in IDLE state.
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
// Send 2 byte long ready-to-receive packet to stimulate host reply
ed_data[0] = SYNC_ED_TYPE_R2R;
ed_data[1] = 0xCB;
SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE);
// Wait shortly for host reply
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
NWK_DELAY(10);
// Check if a command packet was received
while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS)
{
// Decode received data
if (len > 0)
{
// Use callback function in application to decode data and react
simpliciti_sync_decode_ap_cmd_callback();
// Get reply data and send out reply packet burst (19 bytes each)
for (i = 0; i < simpliciti_reply_count; i++)
{
NWK_DELAY(10);
simpliciti_sync_get_data_callback(i);
SMPL_SendOpt(sLinkID1, simpliciti_data, BM_SYNC_DATA_LENGTH, SMPL_TXOPTION_NONE);
}
}
}
// Put radio back to sleep
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
break;
}
}
}
// *************************************************************************************************
// @fn reset_simpliciti
// @brief Reset flag enabling reconnection
// @param none
// @return none
// *************************************************************************************************
void reset_simpliciti(void)
{
sInit_done = 0;
}
// *************************************************************************************************
// @fn simpliciti_main_sync
// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply.
// Decode received host command and trigger action.
// @param none
// @return none
// *************************************************************************************************
static uint8_t Listen_Callback(linkID_t port)
{
uint8_t len;
/* is the callback for the link ID we want to handle? */
if (port == sLinkID2)
{
/* yes. go get the frame. we know this call will succeed. */
if ((SMPL_SUCCESS == SMPL_Receive(sLinkID2, simpliciti_data, &len)) && len)
{
simpliciti_2chronos_decode_data_callback();
return 1;
}
}
/* keep frame for later handling */
return 0;
}
void rf2chronos_send_sync(void)
{
// check what to send
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
// choose what data to send
simpliciti_data[0] = SYNC_2CHRONOS_CMD_DATA_SYNC;
while (simpliciti_data[0] != SYNC_2CHRONOS_CMD_ACK)
{
simpliciti_2chronos_get_data_callback();
SMPL_Send(sLinkID2, simpliciti_data, BM_SYNC_DATA_LENGTH);
NWK_DELAY(60);
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
// Break when flag bit SIMPLICITI_TRIGGER_STOP is set
if (getFlag(simpliciti_flag, SIMPLICITI_SEND_AND_TRIGGER_STOP))
{
// Clean up SimpliciTI stack to enable restarting
sInit_done = 0;
simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
break;
}
}
// SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);
// Put radio back to sleep
// SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
simpliciti_flag = SIMPLICITI_STATUS_LINKED;
simpliciti_flag |= SIMPLICITI_2CHRONOS_LISTEN;
}
In teoria vorrei semplicemente far comunicare tra loro gli orologi solo in presenza di un terzo oggetto che trasmette sempre un segnale a una certa frequenza.
Poi far valutare il parametro RSSI...
Ogni suggerimento e ben accetto!!
Per ora mi dedico ad approfondire un po simpliciti in attesa di risvolti
Si prega Accedi o Crea un account a partecipare alla conversazione.
- cardis
- Autore della discussione
- New Member
Riduci
Di più
- Messaggi: 18
- Ringraziamenti ricevuti 0
12 Anni 1 Mese fa #9
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: eZ-430 Chronos !!
...purtroppo ho usato progetti belli e fatti e al massimo importato alcune informazioni da un progetto all'interno del Packet sniffer, in maniera da far funzionare lo sniffer e farli vedere la comunicazione che mi interessava.
...ora sei piu' esperto di me!
Ti consiglio di fare una domanda al technical support TI.
Tra i ragazzi del technical support ci sono persone esperte di SempliciTi.
Sicuramente ti sapranno indicare.
...poi pero' facci sapere la risposta!
Saluti,
Mauro
...ora sei piu' esperto di me!
Ti consiglio di fare una domanda al technical support TI.
Tra i ragazzi del technical support ci sono persone esperte di SempliciTi.
Sicuramente ti sapranno indicare.
...poi pero' facci sapere la risposta!
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
11 Anni 11 Mesi fa #10
da cardis
Risposta da cardis al topic Re: eZ-430 Chronos !!
Alla fine ho ripiegato sull'uso di un terzo chronos. L'idea di usare l'RF acces point del chronos come terza architetura da gestire (con IAR) non si è rivelata una buona idea...
Ora sto rivedendo il codice del chronos dall'inizio per modificare le parti che mi interessano piuttosto che riprogrammarlo per intero.
Per simpliciti ho risolto alcuni miei dubbi in linea teorica, in pratica scrivere ogni volta un codice da zero sul chronos non mi sembra l'idea più rapida per risolvere il lato pratico:)
Per ovviare ho visto una board della olimex sui cc430
www.olimex.com/Products/MSP430/Starter/MSP430-CCRFLCD/
mi sembra una buona alternativa per sperimentare parte di codice che poi integrerò nel chronos. Il relativo compilatore costa sui 14 euro. Sono affidabili come schede?
Il corso sugli MSP430 sta diventando una "dritta" indispensabile a momenti !!
Ora sto rivedendo il codice del chronos dall'inizio per modificare le parti che mi interessano piuttosto che riprogrammarlo per intero.
Per simpliciti ho risolto alcuni miei dubbi in linea teorica, in pratica scrivere ogni volta un codice da zero sul chronos non mi sembra l'idea più rapida per risolvere il lato pratico:)
Per ovviare ho visto una board della olimex sui cc430
www.olimex.com/Products/MSP430/Starter/MSP430-CCRFLCD/
mi sembra una buona alternativa per sperimentare parte di codice che poi integrerò nel chronos. Il relativo compilatore costa sui 14 euro. Sono affidabili come schede?
Il corso sugli MSP430 sta diventando una "dritta" indispensabile a momenti !!
Si prega Accedi o Crea un account a partecipare alla conversazione.
- cardis
- Autore della discussione
- New Member
Riduci
Di più
- Messaggi: 18
- Ringraziamenti ricevuti 0
Moderatori: Mauro Laurenti, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.
Login
© LaurTec 2006 - 2024