From fd3ff268c86c26052491e4ca241ad89257730456 Mon Sep 17 00:00:00 2001 From: Daniel Poelzleithner Date: Sat, 10 Jul 2010 04:20:45 +0200 Subject: [PATCH] large update to sleep clock code and simplicti * implemented a nice send and receive framework. Code in simplic_tx_only loop can request receive window. In this window the recv of rf will be active and a R2R (ready to receive) package is sent. By then the AP should have filled outgoing buffer and a received handler is called. * made the sleep clock use initialisation. When starting the sleep clock, a new session id is requested that is sent with every package (3 bits), together with the couter (5 bits). When initialized a hash of the hardware address is sent so the clock can detect which watch is running. Also a currently unused program id can be sent to select the watch program later on. --- ezchronos.c | 11 +- logic/phase_clock.c | 48 +++--- logic/phase_clock.h | 19 ++- logic/rfsimpliciti.c | 143 ++++++++++-------- logic/rfsimpliciti.h | 15 +- .../application/End_Device/main_ED_BM.c | 108 +++++++++---- simpliciti/simpliciti.h | 1 + 7 files changed, 217 insertions(+), 128 deletions(-) diff --git a/ezchronos.c b/ezchronos.c index 00dd753..e408aaf 100644 --- a/ezchronos.c +++ b/ezchronos.c @@ -76,6 +76,10 @@ #ifdef CONFIG_EGGTIMER #include "eggtimer.h" #endif +#ifdef CONFIG_PHASE_CLOCK +#include "phase_clock.h" +#endif + // ************************************************************************************************* @@ -134,8 +138,6 @@ extern u8 ps_write_register(u8 address, u8 data); // ************************************************************************************************* int main(void) { - volatile u8 ps; - // Init MCU init_application(); @@ -374,6 +376,11 @@ void init_global_variables(void) reset_eggtimer(); #endif +#ifdef CONFIG_PHASE_CLOCK + // default program + sPhase.program = 0; +#endif + // Reset SimpliciTI stack reset_rf(); diff --git a/logic/phase_clock.c b/logic/phase_clock.c index 66d599b..531a113 100755 --- a/logic/phase_clock.c +++ b/logic/phase_clock.c @@ -143,12 +143,16 @@ void sx_phase(u8 line) // Exit if battery voltage is too low for radio operation if (sys.flag.low_battery) return; + sPhase.session = 0; + sPhase.out_nr = 0; + sPhase.data_nr = 0; + // Exit if BlueRobin stack is active #ifndef ELIMINATE_BLUEROBIN if (is_bluerobin()) return; #endif // Start SimpliciTI in tx only mode - start_simpliciti_tx_only(SIMPLICITI_PHASE_CLOCK); + start_simpliciti_tx_only(SIMPLICITI_PHASE_CLOCK_START); } u8 diff(u8 x1, u8 x2) { @@ -169,31 +173,23 @@ u8 diff(u8 x1, u8 x2) { // @return none // ************************************************************************************************* void phase_clock_calcpoint() { - u16 x,y,z,res = 0; -// char *str; - u8 i = 0; - for(i=1;i> 8) & 0xFF; - - //memcpy(&sPhase.out + sPhase.out_nr, &res, sizeof(u16)); - // reset stack index - //sPhase.out_nr += 2; - sPhase.data_nr = 0; + u16 x,y,z,res; + x = y = z = res = 0; + + u8 i = 0; + for(i=1;i SLEEP_BUFFER-1) { - phase_clock_calcpoint(); - display_symbol(LCD_ICON_BEEPER1, SEG_OFF); - display_symbol(LCD_ICON_BEEPER2, SEG_OFF); - display_symbol(LCD_ICON_BEEPER3, SEG_OFF); - /*simpliciti_data[1] = sPhase.out[0]; - simpliciti_data[2] = sPhase.out[1]; - simpliciti_data[3] = packet_counter++; //8>>sPhase.out[1]&&0xFF; - simpliciti_payload_length = 4; - - simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; - */ - } else { - // copy current value onto the stack - //memcpy(&sPhase.data[sPhase.data_nr][0], &sAccel.xyz, sizeof(u8)*3); - sPhase.data[sPhase.data_nr][0] = sAccel.xyz[0]; + if (sPhase.data_nr > SLEEP_DATA_BUFFER-1) { + phase_clock_calcpoint(); + display_symbol(LCD_ICON_BEEPER1, SEG_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF); + + } else { + // copy current value onto the stack + //memcpy(&sPhase.data[sPhase.data_nr][0], &sAccel.xyz, sizeof(u8)*3); + sPhase.data[sPhase.data_nr][0] = sAccel.xyz[0]; sPhase.data[sPhase.data_nr][1] = sAccel.xyz[1]; - sPhase.data[sPhase.data_nr][2] = sAccel.xyz[2]; + sPhase.data[sPhase.data_nr][2] = sAccel.xyz[2]; //simpliciti_data[3] = sAccel.xyz[2]; - sPhase.data_nr++; - } + sPhase.data_nr++; + } //str = itoa(accel_data, 3, 0); - if (sPhase.out_nr > SLEEP_OUT_BUFFER-1) + if ((sPhase.out_nr > SLEEP_OUT_BUFFER-1)) { // Reset counter sPhase.out_nr = 0; - - // copy out buffer into the simplicti out buffer skip prefix - //memcpy(&simpliciti_data+sizeof(u8), &sPhase.out, PHASE_CLOCK_SEND_LENGTH); - for(i=0; i < SLEEP_OUT_BUFFER; i++) { - //if (((2**17)-1) - // FIXME: overflow detection ? - res += sPhase.out[i]; - } - simpliciti_data[3] = packet_counter++; - simpliciti_data[2] = res & 0xFF; - simpliciti_data[1] = (res >> 8) & 0xFF; - - simpliciti_payload_length = 4; - - //simpliciti_data[0] = SIMPLICITI_PHASE_CLOCK_EVENTS; - // Trigger packet sending - // str = itoa(simpliciti_data[2], 2, 0); - // clear_line(LINE1); - // display_chars(LCD_SEG_L2_5_0, str, SEG_ON); - // Force full display update - //display.flag.full_update = 1; - //str = itoa(simpliciti_data[1], 2, 0); - // display_chars(LCD_SEG_L2_5_2, str, SEG_ON); - //display_chars(LCD_SEG_L1_3_0, str, SEG_ON); - //str = itoa(simpliciti_data[2], 2, 0); - //display_chars(LCD_SEG_L1_1_0, str, SEG_ON); - - //display_symbol(LCD_ICON_RECORD, SEG_ON); - simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; - display_symbol(LCD_ICON_BEEPER1, SEG_ON); - display_symbol(LCD_ICON_BEEPER2, SEG_ON); - display_symbol(LCD_ICON_BEEPER3, SEG_ON); + res = 0; + + for(i=0; i < SLEEP_OUT_BUFFER; i++) { + //if (((2**17)-1)) + // FIXME: overflow detection ? + res += sPhase.out[i]; + } + packet_counter = (packet_counter+1)%SLEEP_MAX_PACKET_COUNTER; + simpliciti_data[3] = (sPhase.session << (8-SLEEP_RF_ID_BIT_LENGHT)) | packet_counter; + simpliciti_data[2] = res & 0xFF; + simpliciti_data[1] = (res >> 8) & 0xFF; + simpliciti_data[0] = SIMPLICITI_PHASE_CLOCK_EVENTS; + + simpliciti_payload_length = 4; + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; } @@ -538,6 +538,27 @@ void simpliciti_get_ed_data_callback(void) } } +// ************************************************************************************************* +// @fn simpliciti_get_rvc_callback +// @brief Callback when data wher received +// @param u8 lenght +// @return none +// ************************************************************************************************* +int simpliciti_get_rvc_callback(u8 len) +{ + + switch (simpliciti_data[0]) + { + case SIMPLICITI_PHASE_CLOCK_START_RESPONSE: // Send watch parameters + sPhase.session = simpliciti_data[1]; + sRFsmpl.mode = SIMPLICITI_PHASE_CLOCK; + simpliciti_data[0] = 0x00; + simpliciti_data[1] = 0x00; + simpliciti_data[2] = 0x00; + return 1; + } + return 0; +} // ************************************************************************************************* // @fn start_simpliciti_sync diff --git a/logic/rfsimpliciti.h b/logic/rfsimpliciti.h index 8813558..7bbd189 100644 --- a/logic/rfsimpliciti.h +++ b/logic/rfsimpliciti.h @@ -52,7 +52,6 @@ extern void display_sync(u8 line, u8 update); extern void send_smpl_data(u16 data); extern u8 is_rf(void); - // ************************************************************************************************* // Defines section @@ -64,6 +63,7 @@ typedef enum SIMPLICITI_BUTTONS, // Transmitting button events SIMPLICITI_SYNC, // Syncing #ifdef CONFIG_PHASE_CLOCK + SIMPLICITI_PHASE_CLOCK_START, // Start new phase SIMPLICITI_PHASE_CLOCK, // Phase Clock is running #endif } simpliciti_mode_t; @@ -77,9 +77,13 @@ typedef enum #define SIMPLICITI_BUTTON_UP (0x30) // SimpliciTI mode flag -#define SIMPLICITI_MOUSE_EVENTS (0x01) -#define SIMPLICITI_KEY_EVENTS (0x02) -#define SIMPLICITI_PHASE_CLOCK_EVENTS (0x03) +#define SIMPLICITI_MOUSE_EVENTS (0x01) +#define SIMPLICITI_KEY_EVENTS (0x02) +#define SIMPLICITI_PHASE_CLOCK_EVENTS (0x03) +#define SIMPLICITI_PHASE_CLOCK_START_EVENTS (0x04) + + +#define SIMPLICITI_PHASE_CLOCK_START_RESPONSE (0x54) // ************************************************************************************************* // Global Variable section @@ -98,4 +102,7 @@ extern unsigned char simpliciti_flag; // ************************************************************************************************* // Extern section +extern void start_simpliciti_tx_only(simpliciti_mode_t mode); + + #endif /*RFSIMPLICITI_H_*/ diff --git a/simpliciti/Applications/application/End_Device/main_ED_BM.c b/simpliciti/Applications/application/End_Device/main_ED_BM.c index 5bdec04..b76cd41 100644 --- a/simpliciti/Applications/application/End_Device/main_ED_BM.c +++ b/simpliciti/Applications/application/End_Device/main_ED_BM.c @@ -35,6 +35,7 @@ #include "bsp_leds.h" #include "bsp_buttons.h" #include "simpliciti.h" +#include "driver/display.h" // ************************************************************************************************* @@ -45,7 +46,7 @@ #define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) // U16 -typedef unsigned short u16; +//typedef unsigned short u16; // ************************************************************************************************* // Prototypes section @@ -60,6 +61,8 @@ extern void Timer0_A4_Delay(u16 ticks); extern unsigned char simpliciti_payload_length; +extern int simpliciti_get_rvc_callback(uint8_t len); + // ************************************************************************************************* // Global Variable section static linkID_t sLinkID1; @@ -211,34 +214,83 @@ unsigned char simpliciti_link(void) // ************************************************************************************************* 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, simpliciti_payload_length, 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; + uint8_t len, i; + uint8_t ed_data[2]; + + while(1) + { + // Get end device data from callback function + simpliciti_get_ed_data_callback(); + + // Get radio ready. Wakes up in IDLE state. + if(getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA) || + getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVED_DATA)) { + + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA)) + { + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + // Acceleration / button events packets are 4 bytes long + SMPL_SendOpt(sLinkID1, simpliciti_data, simpliciti_payload_length, SMPL_TXOPTION_NONE); + + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA); + } + // Receive data when flag bit SIMPLICITI_TRIGGER_RECEIVE_DATA is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVE_DATA)) { + // Send 2 byte long ready-to-receive packet to stimulate host reply + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVE_DATA); + + // clean up tha buffer first + simpliciti_data[0] = 0x00; + simpliciti_data[1] = 0x00; + simpliciti_data[3] = 0x00; + simpliciti_data[4] = 0x00; + + // generate a ready to receive packet + ed_data[0] = SYNC_ED_TYPE_R2R; + ed_data[1] = 0xCB; + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); + NWK_DELAY(10); + + // we try to receive 9 times by sending a R2R packet + for (i = 0; i < 10; i++) { + SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE); + + //WDTCTL = WDTPW + WDTHOLD; + + // Wait shortly for host reply + NWK_DELAY(10); + + while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS) + { + if (len > 0) + { + // Decode received data + if(simpliciti_get_rvc_callback(len)) + { + // stop retry loop + i = 10; + break; + } + } + Timer0_A4_Delay(CONV_MS_TO_TICKS(50)); + } + } + } + + // Put radio back to SLEEP state + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 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; + break; + } } - } } diff --git a/simpliciti/simpliciti.h b/simpliciti/simpliciti.h index fb50e6c..ff97d1c 100644 --- a/simpliciti/simpliciti.h +++ b/simpliciti/simpliciti.h @@ -106,6 +106,7 @@ extern unsigned char simpliciti_flag; #define SIMPLICITI_TRIGGER_SEND_DATA (BIT3) #define SIMPLICITI_TRIGGER_RECEIVED_DATA (BIT4) #define SIMPLICITI_TRIGGER_STOP (BIT5) +#define SIMPLICITI_TRIGGER_RECEIVE_DATA (BIT6) // Radio frequency offset read from calibration memory // Compensates crystal deviation from 26MHz nominal value