00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #include "gzll.h"
00019 #include <string.h>
00020
00021 #ifdef __C51__
00022 #include <intrins.h>
00023 #elif __ICC8051__
00024 #include <intrinsics.h>
00025 #endif
00026
00027 #include "hal_delay.h"
00028
00029 #define GZLL_PULSE_FIX
00030
00031
00032
00033
00034
00048 static uint8_t gzll_lfsr_get(uint8_t seed, uint8_t max_limit);
00049
00053 void gzll_delay_50us(uint8_t n);
00054
00059 typedef enum
00060 {
00061 GZLL_CHANNEL_PREVIOUS_SUCCESS,
00062 GZLL_CHANNEL_RANDOM,
00063 GZLL_CHANNEL_ESTIMATED,
00064 GZLL_CHANNEL_NEXT_INDEX
00065 } gzll_new_tx_ch_t;
00066
00076 static void gzll_start_new_tx(gzll_new_tx_ch_t channel_select);
00077
00082 static void gzll_reload_tries_pr_channel_counter(void);
00083
00089 static void gzll_set_radio_auto_retries(void);
00090
00094 static void gzll_set_system_idle(void);
00095
00100 static void gzll_interupts_disable_rfck_enable(void);
00101
00106 static void gzll_interupts_enable_rfck_disable(void);
00107
00108
00109
00110
00111
00116 static void gzll_chm_reset_rx_channel_index(void);
00117
00124 static uint8_t gzll_chm_get_current_rx_channel(void);
00125
00131 static uint8_t gzll_chm_get_next_rx_channel(void);
00132
00138 static void gzll_chm_hold_rx_channel(void);
00139
00144 static void gzll_chm_execute(void);
00145
00153 static uint16_t gzll_chm_get_rx_ce_offset(void);
00154
00163 static uint16_t gzll_chm_get_tx_ce_offset(void);
00164
00165
00166
00167
00168
00174 static void gzll_set_radio_power_on(bool on);
00175
00176
00177
00178
00179
00194 static void gzll_crypt_payload_assemble(uint8_t *dst, uint8_t *src, uint8_t length_src, uint8_t *aes_key);
00195
00211 static void gzll_crypt_payload_disassemble(uint8_t *dst, uint8_t *src, uint8_t length_src, uint8_t *aes_key);
00212
00213
00214
00215
00216
00217
00218
00219
00220 static uint16_t xdata gzll_dyn_params[GZLL_DYN_PARAM_SIZE];
00221
00222
00223
00224
00225 static uint8_t xdata gzll_channel_tab[GZLL_MAX_CHANNEL_TAB_SIZE] = GZLL_DEFAULT_CHANNEL_TAB;
00226
00227
00228
00229
00230 static uint8_t xdata gzll_p0_adr[GZLL_ADDRESS_WIDTH] = GZLL_DEFAULT_ADDRESS_PIPE0;
00231
00232 #ifdef __C51__
00233 static uint16_t bdata gzll_bit_storage;
00234 #define GZLL_BIT(_var, _bitnum) sbit _var = gzll_bit_storage ^ _bitnum
00235 #else
00236 #define GZLL_BIT(_var, _bitnum) static xdata bool volatile _var
00237 #endif
00238
00239
00240
00241
00242 GZLL_BIT(gzll_tx_success_f, 0);
00243 GZLL_BIT(gzll_tx_setup_modified, 1);
00244 GZLL_BIT(gzll_rx_setup_modified, 2);
00245 GZLL_BIT(gzll_sync_on, 3);
00246 GZLL_BIT(gzll_rx_dr, 4);
00247 GZLL_BIT(gzll_rx_power_high_f, 5);
00248 GZLL_BIT(gzll_radio_active_f, 6);
00249 GZLL_BIT(gzll_power_on, 7);
00250
00251 static xdata uint8_t volatile gzll_current_tx_pipe;
00252 static xdata uint8_t volatile gzll_current_tx_payload_length;
00253 static xdata uint8_t volatile gzll_channel_tab_size;
00254 static xdata uint8_t volatile gzll_channel_tab_index;
00255 static xdata gzll_states_t volatile gzll_state_var;
00256
00257
00258
00259
00260 GZLL_BIT(gzll_pending_tx_start, 8);
00261 GZLL_BIT(gzll_pending_goto_idle, 9);
00262 GZLL_BIT(gzll_timer_period_modified, 10);
00263 GZLL_BIT(gzll_claim_rfck_en, 11);
00264 GZLL_BIT(b_rfce, 12);
00265
00266
00267
00268
00269
00270 static xdata uint8_t gzll_ack_rx_pipe_fifo[3];
00271 static xdata uint8_t gzll_ack_rx_pipe_fifo_cnt;
00272
00273
00274
00275
00276 static xdata uint8_t gzll_tries_pr_channel_counter;
00277 static xdata uint16_t gzll_sync_period;
00278 static xdata uint16_t gzll_timeout_counter;
00279
00280
00281
00282
00283 static xdata uint16_t gzll_channel_switch_counter;
00284 static xdata uint16_t gzll_try_counter;
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 #define GZLL_INTERRUPTS_DISABLE() do{ \
00297 RFEN = 0; \
00298 TIMEREN = 0; \
00299 }while(0)
00300
00301 #define GZLL_INTERRUPTS_ENABLE() do{ \
00302 RFEN = 1; \
00303 TIMEREN = 1; \
00304 }while(0)
00305
00306 #ifdef GZLL_PULSE_FIX
00307 #define GZLL_RFCK_ENABLE() do{ \
00308 gzll_claim_rfck_en = 1; \
00309 RFCKEN = 1; \
00310 } while(0)
00311
00312 #define GZLL_RFCK_DISABLE() do{ \
00313 gzll_claim_rfck_en = 0; \
00314 RFCKEN = b_rfce; \
00315 } while(0)
00316
00317 #define GZLL_RFCE_PULSE() do{ \
00318 RFCKEN = 1; \
00319 RFCE = 1; \
00320 b_rfce = true; \
00321 delay_us(10); \
00322 RFCE = 0; \
00323 } while(false)
00324
00325 #define GZLL_RFCE_HIGH() do{ \
00326 RFCKEN = 1; \
00327 RFCE = 1; \
00328 b_rfce = true; \
00329 } while(false)
00330
00331 #define GZLL_RFCE_LOW() do{ \
00332 RFCE = 0; \
00333 RFCKEN = gzll_claim_rfck_en; \
00334 b_rfce = false; \
00335 } while(0)
00336
00337 #else
00338
00339 #define GZLL_RFCK_ENABLE() do{ \
00340 gzll_claim_rfck_en = 1; \
00341 RFCKEN = 1; \
00342 } while(0)
00343
00344 #define GZLL_RFCK_DISABLE() do{ \
00345 gzll_claim_rfck_en = 0; \
00346 RFCKEN = RFCE; \
00347 } while(0)
00348
00349
00350 #define GZLL_RFCE_HIGH() do{ \
00351 RFCKEN = 1; \
00352 RFCE = 1; \
00353 } while(false)
00354
00355 #define GZLL_RFCE_PULSE() GZLL_RFCE_HIGH()
00356
00357 #define GZLL_RFCE_LOW() do{ \
00358 RFCE = 0; \
00359 RFCKEN = gzll_claim_rfck_en; \
00360 } while(0)
00361
00362 #endif
00363
00364 static void gzll_interupts_disable_rfck_enable()
00365 {
00366 uint8_t t_ea;
00367 t_ea = EA;
00368 EA = 0;
00369 GZLL_INTERRUPTS_DISABLE();
00370 GZLL_RFCK_ENABLE();
00371 EA = t_ea;
00372 }
00373
00374 static void gzll_interupts_enable_rfck_disable()
00375 {
00376 GZLL_INTERRUPTS_ENABLE();
00377 GZLL_RFCK_DISABLE();
00378 }
00379
00380
00381
00382
00383
00384 void gzll_init(void)
00385 {
00386 uint8_t temp_adr[GZLL_ADDRESS_WIDTH] = GZLL_DEFAULT_ADDRESS_PIPE1;
00387
00388 gzll_interupts_disable_rfck_enable();
00389 GZLL_RFCE_LOW();
00390
00391 hal_nrf_enable_ack_payload(true);
00392 hal_nrf_enable_dynamic_payload(true);
00393 hal_nrf_setup_dynamic_payload(0xff);
00394
00395
00396
00397
00398 gzll_channel_tab_index = 0;
00399 gzll_channel_tab_size = GZLL_DEFAULT_CHANNEL_TAB_SIZE;
00400
00401 gzll_pending_goto_idle = false;
00402 gzll_timer_period_modified = false;
00403
00404 gzll_current_tx_pipe = 0;
00405 gzll_pending_tx_start = false;
00406 gzll_tx_setup_modified = true;
00407 gzll_rx_setup_modified = true;
00408 gzll_radio_active_f = false;
00409 gzll_tx_success_f = true;
00410
00411 gzll_sync_period = 0;
00412 gzll_sync_on = false;
00413
00414 gzll_rx_dr = false;
00415 gzll_rx_power_high_f = false;
00416 gzll_ack_rx_pipe_fifo_cnt = 0;
00417
00418
00419
00420
00421 hal_nrf_set_address(HAL_NRF_PIPE0, gzll_p0_adr);
00422 hal_nrf_set_address(HAL_NRF_PIPE1, temp_adr);
00423
00424 temp_adr[0] = GZLL_DEFAULT_ADDRESS_PIPE2;
00425 hal_nrf_set_address(HAL_NRF_PIPE2, temp_adr);
00426
00427 temp_adr[0] = GZLL_DEFAULT_ADDRESS_PIPE3;
00428 hal_nrf_set_address(HAL_NRF_PIPE3, temp_adr);
00429
00430 temp_adr[0] = GZLL_DEFAULT_ADDRESS_PIPE4;
00431 hal_nrf_set_address(HAL_NRF_PIPE4, temp_adr);
00432
00433 temp_adr[0] = GZLL_DEFAULT_ADDRESS_PIPE5;
00434 hal_nrf_set_address(HAL_NRF_PIPE5, temp_adr);
00435
00436
00437
00438
00439 hal_nrf_set_rf_channel(gzll_channel_tab[gzll_channel_tab_index]);
00440
00441
00442
00443
00444 gzll_dyn_params[GZLL_PARAM_DEVICE_MODE] = GZLL_DEFAULT_PARAM_DEVICE_MODE;
00445 gzll_dyn_params[GZLL_PARAM_TX_TIMEOUT] = GZLL_DEFAULT_PARAM_TX_TIMEOUT;
00446 gzll_dyn_params[GZLL_PARAM_TX_ATTEMPTS_PR_CHANNEL_WHEN_SYNC_ON] = GZLL_DEFAULT_PARAM_TX_ATTEMPTS_PR_CHANNEL_WHEN_SYNC_ON;
00447 gzll_dyn_params[GZLL_PARAM_TX_ATTEMPTS_PR_CHANNEL_WHEN_SYNC_OFF] = GZLL_DEFAULT_PARAM_TX_ATTEMPTS_PR_CHANNEL_WHEN_SYNC_OFF;
00448 gzll_dyn_params[GZLL_PARAM_HOST_MODE] = GZLL_DEFAULT_PARAM_HOST_MODE;
00449 gzll_dyn_params[GZLL_PARAM_RX_PIPES] = GZLL_DEFAULT_PARAM_RX_PIPES;
00450 gzll_dyn_params[GZLL_PARAM_CRYPT_PIPES] = GZLL_DEFAULT_PARAM_CRYPT_PIPES;
00451 gzll_dyn_params[GZLL_PARAM_RX_TIMEOUT] = GZLL_DEFAULT_PARAM_RX_TIMEOUT;
00452 gzll_dyn_params[GZLL_PARAM_HOST_MODE_1_CYCLE_PERIOD] = GZLL_DEFAULT_PARAM_HOST_MODE_1_CYCLE_PERIOD;
00453 gzll_dyn_params[GZLL_PARAM_RX_PERIOD] = GZLL_DEFAULT_PARAM_RX_PERIOD;
00454 gzll_dyn_params[GZLL_PARAM_RX_PERIOD_MODIFIER] = GZLL_DEFAULT_PARAM_RX_PERIOD_MODIFIER;
00455 gzll_dyn_params[GZLL_PARAM_RX_CHANNEL_HOLD_PERIODS] = GZLL_DEFAULT_PARAM_RX_CHANNEL_HOLD_PERIODS;
00456 gzll_dyn_params[GZLL_PARAM_OUTPUT_POWER] = GZLL_DEFAULT_PARAM_OUTPUT_POWER;
00457 gzll_dyn_params[GZLL_PARAM_POWER_DOWN_IDLE_ENABLE] = GZLL_DEFAULT_PARAM_POWER_DOWN_IDLE_ENABLE;
00458 gzll_dyn_params[GZLL_PARAM_MAX_SYNC_PERIOD] = GZLL_DEFAULT_PARAM_MAX_SYNC_PERIOD;
00459 gzll_dyn_params[GZLL_PARAM_COLLISION_CHANNEL_SWITCH_LIMIT] = GZLL_DEFAULT_PARAM_COLLISION_CHANNEL_SWITCH_LIMIT;
00460
00461
00462
00463
00464 hal_nrf_set_output_power((hal_nrf_output_power_t) gzll_dyn_params[GZLL_PARAM_OUTPUT_POWER]);
00465
00466
00467
00468
00469 hal_nrf_set_datarate(GZLL_HAL_DATARATE);
00470 hal_nrf_set_crc_mode(GZLL_CRC);
00471 hal_nrf_set_address_width(GZLL_ADDRESS_WIDTH);
00472
00473
00474
00475
00476
00477 hal_nrf_get_clear_irq_flags();
00478
00479 hal_nrf_flush_rx();
00480 hal_nrf_flush_tx();
00481
00482 gzll_set_timer_period(GZLL_DEFAULT_PARAM_RX_PERIOD);
00483 gzll_set_system_idle();
00484 gzll_interupts_enable_rfck_disable();
00485 }
00486
00487 void gzll_set_param(gzll_dyn_params_t param, uint16_t val)
00488 {
00489 ASSERT((gzll_state_var == GZLL_IDLE));
00490 ASSERT((param < GZLL_DYN_PARAM_SIZE));
00491 ASSERT(!(param == GZLL_PARAM_DEVICE_MODE && val > GZLL_DEVICE_MODE_4));
00492 ASSERT(!(param == GZLL_PARAM_HOST_MODE && val > GZLL_HOST_MODE_1));
00493 ASSERT(!(param == GZLL_PARAM_RX_PIPES && val > 0x3f));
00494 ASSERT(!(param == GZLL_PARAM_CRYPT_PIPES && val > GZLL_MAX_CRYPT_PIPES_VAL));
00495 ASSERT(!(param == GZLL_PARAM_OUTPUT_POWER && val > 3));
00496
00497 gzll_interupts_disable_rfck_enable();
00498
00499 if(param < GZLL_DYN_PARAM_SIZE)
00500 {
00501 gzll_dyn_params[param] = val;
00502
00503 switch(param)
00504 {
00505 case GZLL_PARAM_DEVICE_MODE:
00506 if((val == GZLL_DEVICE_MODE_0 || val == GZLL_DEVICE_MODE_1))
00507 {
00508 gzll_sync_on = false;
00509 }
00510 break;
00511 case GZLL_PARAM_POWER_DOWN_IDLE_ENABLE:
00512 if(val == 1)
00513 {
00514 gzll_set_radio_power_on(false);
00515 }
00516 break;
00517 case GZLL_PARAM_RX_PERIOD:
00518 gzll_timer_period_modified = 1;
00519 break;
00520 case GZLL_PARAM_OUTPUT_POWER:
00521 hal_nrf_set_output_power((hal_nrf_output_power_t)gzll_dyn_params[GZLL_PARAM_OUTPUT_POWER]);
00522 break;
00523 case GZLL_PARAM_RX_PIPES:
00524 gzll_rx_setup_modified = true;
00525 break;
00526 }
00527 }
00528
00529 gzll_interupts_enable_rfck_disable();
00530 }
00531
00532 uint16_t gzll_get_param_max(gzll_dyn_params_t param)
00533 {
00534 uint16_t param_max[GZLL_DYN_PARAM_SIZE] = GZLL_PARAMS_MAX;
00535
00536 return param_max[param];
00537 }
00538
00539 uint16_t gzll_get_param(gzll_dyn_params_t param)
00540 {
00541 ASSERT((param < GZLL_DYN_PARAM_SIZE));
00542
00543 gzll_interupts_disable_rfck_enable();
00544
00545 if(param < GZLL_DYN_PARAM_SIZE)
00546 {
00547 gzll_interupts_enable_rfck_disable();
00548 return gzll_dyn_params[param];
00549 }
00550 else
00551 {
00552 gzll_interupts_enable_rfck_disable();
00553 return 0;
00554 }
00555 }
00556
00557 uint8_t gzll_get_channel_tab_size()
00558 {
00559 return gzll_channel_tab_size;
00560 }
00561
00562 void gzll_get_channels(uint8_t *channels)
00563 {
00564 memcpy(channels, gzll_channel_tab, gzll_channel_tab_size);
00565 }
00566
00567 void gzll_set_channels(uint8_t *channels, uint8_t channel_tab_size)
00568 {
00569 gzll_interupts_disable_rfck_enable();
00570
00571 ASSERT((gzll_state_var == GZLL_IDLE));
00572 ASSERT((channel_tab_size <= GZLL_MAX_CHANNEL_TAB_SIZE));
00573
00574 gzll_channel_tab_index = 0;
00575 gzll_channel_tab_size = channel_tab_size;
00576 memcpy(gzll_channel_tab, channels, gzll_channel_tab_size);
00577
00578 hal_nrf_set_rf_channel(gzll_channel_tab[gzll_channel_tab_index]);
00579
00580 gzll_interupts_enable_rfck_disable();
00581 }
00582
00583 void gzll_set_address(hal_nrf_address_t pipe, const uint8_t *address)
00584 {
00585 ASSERT((gzll_state_var == GZLL_IDLE));
00586 ASSERT((pipe <= 5));
00587
00588 gzll_interupts_disable_rfck_enable();
00589
00590 gzll_tx_setup_modified = true;
00591 gzll_rx_setup_modified = true;
00592
00593 if(pipe == HAL_NRF_PIPE0)
00594 {
00595 memcpy(gzll_p0_adr, (uint8_t*)address, GZLL_ADDRESS_WIDTH);
00596 }
00597
00598 hal_nrf_set_address(pipe, address);
00599
00600 gzll_interupts_enable_rfck_disable();
00601 }
00602
00603 void gzll_get_address(uint8_t pipe, uint8_t* address)
00604 {
00605 ASSERT((pipe <= 5));
00606 ASSERT(address != NULL);
00607
00608 gzll_interupts_disable_rfck_enable();
00609
00610 hal_nrf_get_address(pipe, address);
00611
00612 gzll_interupts_enable_rfck_disable();
00613 }
00614
00615 #ifndef GZLL_DEVICE_ONLY
00616
00617
00618 void gzll_rx_start()
00619 {
00620 uint8_t i;
00621
00622 gzll_goto_idle();
00623
00624 if(gzll_rx_setup_modified)
00625 {
00626 gzll_interupts_disable_rfck_enable();
00627
00628 gzll_rx_setup_modified = false;
00629 gzll_tx_setup_modified = true;
00630
00631
00632
00633
00634 hal_nrf_set_address(HAL_NRF_PIPE0, gzll_p0_adr);
00635
00636
00637
00638
00639 hal_nrf_close_pipe(HAL_NRF_ALL);
00640 for(i = 0; i < 6; i++)
00641 {
00642 if(gzll_dyn_params[GZLL_PARAM_RX_PIPES] & (1 << i))
00643 {
00644 hal_nrf_open_pipe((hal_nrf_address_t)i, EN_AA);
00645 }
00646 }
00647 hal_nrf_set_operation_mode(HAL_NRF_PRX);
00648 }
00649
00650 gzll_set_radio_power_on(true);
00651 gzll_timeout_counter = 0;
00652 gzll_state_var = GZLL_HOST_ACTIVE;
00653
00654 GZLL_RFCE_HIGH();
00655 gzll_interupts_enable_rfck_disable();
00656 }
00657
00658 bool gzll_ack_payload_write(const uint8_t *src, uint8_t length, uint8_t pipe)
00659 {
00660 ASSERT(length <= GZLL_MAX_ACK_PAYLOAD_LENGTH && length > 0);
00661 ASSERT(pipe <= 5);
00662
00663 gzll_interupts_disable_rfck_enable();
00664
00665 if(length == 0 || (length > GZLL_MAX_ACK_PAYLOAD_LENGTH) || hal_nrf_tx_fifo_full())
00666 {
00667 gzll_interupts_enable_rfck_disable();
00668 return false;
00669 }
00670 hal_nrf_write_ack_payload(pipe, src, length);
00671 gzll_interupts_enable_rfck_disable();
00672 return true;
00673 }
00674
00675 #endif
00676
00677 #define GZLL_UPLOAD_PAYLOAD_TO_RADIO() hal_nrf_write_tx_payload(src, length)
00678
00679 #ifndef GZLL_HOST_ONLY
00680
00681 bool gzll_tx_data(const uint8_t *src, uint8_t length, uint8_t pipe)
00682 {
00683 uint8_t temp_address[GZLL_ADDRESS_WIDTH];
00684 uint16_t temp;
00685
00686 ASSERT(length <= GZLL_MAX_FW_PAYLOAD_LENGTH && length > 0);
00687 ASSERT(pipe <= 5);
00688
00689
00690
00691
00692
00693 if(length == 0 || length > GZLL_MAX_FW_PAYLOAD_LENGTH)
00694 {
00695 return false;
00696 }
00697
00698 gzll_current_tx_payload_length = length;
00699
00700 if(gzll_state_var == GZLL_HOST_ACTIVE)
00701 {
00702 gzll_goto_idle();
00703 }
00704
00705 gzll_interupts_disable_rfck_enable();
00706
00707
00708
00709
00710
00711 if(pipe != gzll_current_tx_pipe)
00712 {
00713 gzll_current_tx_pipe = pipe;
00714 gzll_tx_setup_modified = true;
00715 }
00716
00717
00718
00719
00720 if(gzll_state_var == GZLL_IDLE)
00721 {
00722 if(gzll_tx_setup_modified)
00723 {
00724 gzll_tx_setup_modified = false;
00725 gzll_rx_setup_modified = true;
00726
00727 hal_nrf_set_operation_mode(HAL_NRF_PTX);
00728 hal_nrf_open_pipe(HAL_NRF_PIPE0, EN_AA);
00729
00730
00731 if(pipe == HAL_NRF_PIPE0)
00732 {
00733 hal_nrf_set_address(HAL_NRF_TX, gzll_p0_adr);
00734 hal_nrf_set_address(HAL_NRF_PIPE0, gzll_p0_adr);
00735 }
00736 else
00737 {
00738
00739
00740 uint8_t bytes_in_buffer;
00741 bytes_in_buffer = hal_nrf_get_address(HAL_NRF_PIPE1, temp_address);
00742 if(pipe != HAL_NRF_PIPE1)
00743 {
00744 switch(pipe)
00745 {
00746 default:
00747 case HAL_NRF_PIPE2:
00748 bytes_in_buffer = hal_nrf_get_address(HAL_NRF_PIPE2, temp_address);
00749 break;
00750 case HAL_NRF_PIPE3:
00751 bytes_in_buffer = hal_nrf_get_address(HAL_NRF_PIPE3, temp_address);
00752 break;
00753 case HAL_NRF_PIPE4:
00754 bytes_in_buffer = hal_nrf_get_address(HAL_NRF_PIPE4, temp_address);
00755 break;
00756 case HAL_NRF_PIPE5:
00757 bytes_in_buffer = hal_nrf_get_address(HAL_NRF_PIPE5, temp_address);
00758 break;
00759 }
00760 }
00761
00762
00763 hal_nrf_set_address(HAL_NRF_PIPE0, temp_address);
00764 hal_nrf_set_address(HAL_NRF_TX, temp_address);
00765
00766
00767
00768
00769
00770
00771
00772 gzll_lfsr_get(pipe, 1);
00773 }
00774 }
00775
00776
00777 gzll_timeout_counter = 0;
00778 gzll_channel_switch_counter = 0;
00779 gzll_try_counter = 0;
00780 hal_nrf_flush_tx();
00781
00782 GZLL_UPLOAD_PAYLOAD_TO_RADIO();
00783
00784 gzll_tx_success_f = false;
00785
00786 temp = gzll_dyn_params[GZLL_PARAM_DEVICE_MODE];
00787
00788 gzll_set_radio_power_on(true);
00789 if(gzll_sync_on)
00790 {
00791 switch(temp)
00792 {
00793 case GZLL_DEVICE_MODE_2:
00794 default:
00795 gzll_start_new_tx(GZLL_CHANNEL_PREVIOUS_SUCCESS);
00796 break;
00797 case GZLL_DEVICE_MODE_3:
00798 gzll_start_new_tx(GZLL_CHANNEL_RANDOM);
00799 break;
00800 case GZLL_DEVICE_MODE_4:
00801 gzll_start_new_tx(GZLL_CHANNEL_ESTIMATED);
00802 break;
00803 }
00804 }
00805 else
00806 {
00807 switch(temp)
00808 {
00809 case GZLL_DEVICE_MODE_0:
00810 case GZLL_DEVICE_MODE_2:
00811 gzll_start_new_tx(GZLL_CHANNEL_PREVIOUS_SUCCESS);
00812 break;
00813 default:
00814 gzll_start_new_tx(GZLL_CHANNEL_RANDOM);
00815 break;
00816 }
00817 }
00818
00819 gzll_state_var = GZLL_DEVICE_ACTIVE;
00820 gzll_interupts_enable_rfck_disable();
00821 return true;
00822 }
00823 else
00824 {
00825
00826
00827
00828
00829 if(!gzll_tx_setup_modified &&
00830 !hal_nrf_tx_fifo_full()
00831 )
00832 {
00833 GZLL_UPLOAD_PAYLOAD_TO_RADIO();
00834 gzll_interupts_enable_rfck_disable();
00835 return true;
00836 }
00837 else
00838 {
00839 gzll_interupts_enable_rfck_disable();
00840 return false;
00841 }
00842 }
00843 }
00844
00845 bool gzll_dev_mode2_rx_channel_match()
00846 {
00847 if(gzll_sync_on)
00848 {
00849 if(gzll_channel_tab_index == gzll_chm_get_next_rx_channel())
00850 {
00851 if((gzll_dyn_params[GZLL_PARAM_HOST_MODE] == GZLL_HOST_MODE_0) ||
00852 gzll_chm_get_tx_ce_offset() == 1)
00853 {
00854 return true;
00855 }
00856 }
00857 return false;
00858 }
00859 else
00860 {
00861 return true;
00862 }
00863 }
00864
00865 bool gzll_tx_success(void)
00866 {
00867 ASSERT(gzll_state_var != GZLL_DEVICE_ACTIVE);
00868
00869 return gzll_tx_success_f;
00870 }
00871
00872 uint16_t gzll_get_tx_attempts(void)
00873 {
00874 ASSERT(gzll_state_var != GZLL_DEVICE_ACTIVE);
00875
00876 return gzll_try_counter;
00877 }
00878
00879 uint16_t gzll_get_tx_channel_switches(void)
00880 {
00881 ASSERT(gzll_state_var != GZLL_DEVICE_ACTIVE)
00882 return gzll_channel_switch_counter;
00883 }
00884
00885 #endif
00886
00887 void gzll_tx_fifo_flush(void)
00888 {
00889 gzll_interupts_disable_rfck_enable();
00890
00891 hal_nrf_flush_tx();
00892
00893 gzll_interupts_enable_rfck_disable();
00894 }
00895
00896
00897 gzll_states_t gzll_get_state(void)
00898 {
00899 return gzll_state_var;
00900 }
00901
00902 bool gzll_radio_active()
00903 {
00904 return gzll_radio_active_f;
00905 }
00906
00907 uint8_t gzll_get_rx_data_ready_pipe_number()
00908 {
00909 uint8_t dr_rx_pipe;
00910
00911 gzll_interupts_disable_rfck_enable();
00912
00913 if(gzll_rx_dr)
00914 {
00915 if(gzll_ack_rx_pipe_fifo_cnt > 0)
00916 {
00917 dr_rx_pipe = gzll_ack_rx_pipe_fifo[gzll_ack_rx_pipe_fifo_cnt - 1];
00918 }
00919 else
00920 {
00921 dr_rx_pipe = hal_nrf_get_rx_data_source();
00922 }
00923 }
00924 else
00925 {
00926 dr_rx_pipe = 0xff;
00927 }
00928
00929 gzll_interupts_enable_rfck_disable();
00930 return dr_rx_pipe;
00931 }
00932
00933 bool gzll_rx_data_ready(uint8_t pipe)
00934 {
00935 uint8_t available_rx_data_pipe;
00936
00937 available_rx_data_pipe = gzll_get_rx_data_ready_pipe_number();
00938
00939 return (available_rx_data_pipe <= 5 && (pipe == 0xff || pipe == available_rx_data_pipe));
00940 }
00941
00942 bool gzll_rx_fifo_read(uint8_t *dst, uint8_t *length, uint8_t *pipe)
00943 {
00944 uint8_t temp_pipe;
00945 uint8_t temp_length;
00946 uint16_t pipe_and_length;
00947
00948 ASSERT(dst != NULL);
00949
00950 gzll_interupts_disable_rfck_enable();
00951
00952 if(gzll_rx_dr)
00953 {
00954 temp_length = hal_nrf_read_rx_payload_width();
00955 if(temp_length <= 32)
00956 {
00957 pipe_and_length = hal_nrf_read_rx_payload(dst);
00958 if(gzll_ack_rx_pipe_fifo_cnt > 0)
00959 {
00960 gzll_ack_rx_pipe_fifo_cnt--;
00961 temp_pipe = gzll_ack_rx_pipe_fifo[gzll_ack_rx_pipe_fifo_cnt];
00962 }
00963 else
00964 {
00965 temp_pipe = (pipe_and_length >> 8);
00966 }
00967
00968
00969
00970
00971
00972
00973 if(hal_nrf_rx_fifo_empty())
00974 {
00975 gzll_rx_dr = false;
00976 }
00977
00978 if(pipe != NULL)
00979 {
00980 *pipe = temp_pipe;
00981 }
00982
00983 if(length != NULL)
00984 {
00985 *length = temp_length;
00986 }
00987
00988 gzll_interupts_enable_rfck_disable();
00989 return true;
00990 }
00991 else
00992 {
00993 gzll_rx_fifo_flush();
00994 }
00995 }
00996
00997 gzll_interupts_enable_rfck_disable();
00998 return false;
00999 }
01000
01001 bool gzll_rx_power_high()
01002 {
01003 return gzll_rx_power_high_f;
01004 }
01005
01006 void gzll_rx_fifo_flush(void)
01007 {
01008 gzll_interupts_disable_rfck_enable();
01009
01010 hal_nrf_flush_rx();
01011 gzll_ack_rx_pipe_fifo_cnt = 0;
01012 gzll_rx_dr = false;
01013
01014 gzll_interupts_enable_rfck_disable();
01015 }
01016
01017 void gzll_goto_idle()
01018 {
01019 if(gzll_state_var == GZLL_DEVICE_ACTIVE)
01020 {
01021 gzll_pending_goto_idle = true;
01022
01023 while(gzll_state_var != GZLL_IDLE)
01024 ;
01025 }
01026 else
01027 {
01028 if(gzll_state_var == GZLL_HOST_ACTIVE)
01029 {
01030 gzll_interupts_disable_rfck_enable();
01031 gzll_set_system_idle();
01032 gzll_interupts_enable_rfck_disable();
01033 }
01034 }
01035 }
01036
01037
01038
01039
01040
01041 static uint8_t gzll_lfsr_get(uint8_t seed, uint8_t max_limit)
01042 {
01043 static xdata uint8_t pseudoreg = 0xff;
01044 uint8_t shiftbit;
01045
01046 if(seed > 0)
01047 {
01048 pseudoreg = seed;
01049 }
01050
01051 shiftbit = (pseudoreg << 7) & 0x80;
01052 shiftbit ^= (pseudoreg << 6) & 0x80;
01053 shiftbit ^= (pseudoreg << 5) & 0x80;
01054 shiftbit ^= (pseudoreg & 0x80);
01055
01056 pseudoreg = (shiftbit | (pseudoreg >> 1));
01057
01058 return pseudoreg % max_limit;
01059 }
01060
01061 void gzll_delay_50us(uint8_t n)
01062 {
01063 uint16_t c;
01064
01065 while(n-- > 0)
01066 {
01067 c = 45;
01068 while(c-- > 0)
01069 ;
01070 }
01071 }
01072
01073 static void gzll_start_new_tx(gzll_new_tx_ch_t channel_select)
01074 {
01075 uint8_t temp;
01076
01077 gzll_reload_tries_pr_channel_counter();
01078 gzll_set_radio_auto_retries();
01079
01080
01081 switch(channel_select)
01082 {
01083 case GZLL_CHANNEL_PREVIOUS_SUCCESS:
01084 default:
01085 temp = gzll_channel_tab_index;
01086 break;
01087 case GZLL_CHANNEL_RANDOM:
01088 temp = gzll_lfsr_get(0, gzll_channel_tab_size);
01089 break;
01090 case GZLL_CHANNEL_ESTIMATED:
01091 temp = gzll_chm_get_next_rx_channel();
01092 break;
01093 case GZLL_CHANNEL_NEXT_INDEX:
01094 temp = gzll_channel_tab_index + 1;
01095 temp = temp % gzll_channel_tab_size;
01096 break;
01097 }
01098
01099
01100 if(temp != gzll_channel_tab_index)
01101 {
01102 gzll_channel_tab_index = temp;
01103 hal_nrf_set_rf_channel(gzll_channel_tab[gzll_channel_tab_index]);
01104 gzll_channel_switch_counter++;
01105 }
01106
01107 if(gzll_sync_on)
01108 {
01109
01110 gzll_pending_tx_start = true;
01111 }
01112 else
01113 {
01114 gzll_radio_active_f = true;
01115 GZLL_RFCE_PULSE();
01116 }
01117
01118 }
01119
01120 static void gzll_reload_tries_pr_channel_counter()
01121 {
01122 if(gzll_sync_on)
01123 {
01124 gzll_tries_pr_channel_counter = gzll_dyn_params[GZLL_PARAM_TX_ATTEMPTS_PR_CHANNEL_WHEN_SYNC_ON];
01125 }
01126 else
01127 {
01128 gzll_tries_pr_channel_counter = gzll_dyn_params[GZLL_PARAM_TX_ATTEMPTS_PR_CHANNEL_WHEN_SYNC_OFF];
01129 }
01130 }
01131
01132 static void gzll_set_radio_auto_retries()
01133 {
01134 if(gzll_tries_pr_channel_counter > 15)
01135 {
01136 hal_nrf_set_auto_retr(15, GZLL_AUTO_RETR_DELAY);
01137 }
01138 else
01139 {
01140 hal_nrf_set_auto_retr((uint8_t)(gzll_tries_pr_channel_counter - 1), GZLL_AUTO_RETR_DELAY);
01141 }
01142 }
01143
01144 static void gzll_set_system_idle(void)
01145 {
01146 GZLL_RFCE_LOW();
01147
01148 if(gzll_state_var == GZLL_HOST_ACTIVE)
01149 {
01150
01151 gzll_delay_50us(GZLL_HOST_CE_LOW_IDLE_DELAY);
01152 }
01153
01154 if(gzll_dyn_params[GZLL_PARAM_POWER_DOWN_IDLE_ENABLE] == 1)
01155 {
01156 gzll_set_radio_power_on(false);
01157 }
01158 else
01159 {
01160 gzll_set_radio_power_on(true);
01161 }
01162
01163 gzll_radio_active_f = false;
01164 gzll_pending_goto_idle = false;
01165 gzll_state_var = GZLL_IDLE;
01166 }
01167
01168
01169
01170
01171 void gzll_radio_isr_function(void)
01172 {
01173 #ifndef GZLL_HOST_ONLY
01174
01175 uint8_t tries;
01176 uint16_t timer_mod_period, temp;
01177 #endif
01178 uint8_t status;
01179
01180 GZLL_INTERRUPTS_DISABLE();
01181 GZLL_RFCK_ENABLE();
01182
01183 status = hal_nrf_clear_irq_flags_get_status();
01184
01185
01186 if(status & ((1<<RX_DR)))
01187 {
01188 gzll_rx_dr = true;
01189 gzll_rx_power_high_f = hal_nrf_get_carrier_detect();
01190 gzll_chm_hold_rx_channel();
01191
01192 #ifndef GZLL_HOST_ONLY
01193
01194
01195
01196
01197 if(gzll_state_var == GZLL_DEVICE_ACTIVE)
01198 {
01199 gzll_ack_rx_pipe_fifo[gzll_ack_rx_pipe_fifo_cnt] = gzll_current_tx_pipe;
01200 if(gzll_ack_rx_pipe_fifo_cnt < 2)
01201 {
01202 gzll_ack_rx_pipe_fifo_cnt++;
01203 }
01204 }
01205 #endif
01206 }
01207
01208
01209 #ifndef GZLL_HOST_ONLY
01210 if((status & (1<<MAX_RT)) || (status & ((1<<TX_DS))))
01211 {
01212 tries = hal_nrf_get_transmit_attempts() + 1;
01213 gzll_tries_pr_channel_counter -= tries;
01214 gzll_try_counter += tries;
01215 }
01216 #endif
01217
01218
01219 if(status & (1<<TX_DS))
01220 {
01221 #ifndef GZLL_HOST_ONLY
01222 if(gzll_state_var == GZLL_DEVICE_ACTIVE)
01223 {
01224 gzll_timer_period_modified = 1;
01225
01226 timer_mod_period = gzll_dyn_params[GZLL_PARAM_RX_PERIOD] - (gzll_dyn_params[GZLL_PARAM_RX_PERIOD_MODIFIER] + ((uint16_t)((GZLL_CONST_BYTES_PR_PACKET * 2) + gzll_current_tx_payload_length) * GZLL_US_PR_BYTE));
01227 if(status & ((1<<RX_DR)))
01228 {
01229 timer_mod_period -= (GZLL_US_PR_BYTE * GZLL_INTERNAL_ACK_PAYLOAD_LENGTH);
01230 }
01231
01232 gzll_set_timer_period(timer_mod_period);
01233
01234 gzll_chm_reset_rx_channel_index();
01235 gzll_chm_hold_rx_channel();
01236
01237 temp = gzll_dyn_params[GZLL_PARAM_DEVICE_MODE];
01238
01239 gzll_sync_period = gzll_dyn_params[GZLL_PARAM_MAX_SYNC_PERIOD];
01240
01241 if(temp == GZLL_DEVICE_MODE_2 || temp == GZLL_DEVICE_MODE_3 || temp == GZLL_DEVICE_MODE_4)
01242 {
01243 gzll_sync_on = true;
01244 }
01245
01246
01247
01248
01249 if(hal_nrf_tx_fifo_empty())
01250 {
01251 gzll_tx_success_f = true;
01252 gzll_set_system_idle();
01253 }
01254 else
01255 {
01256 gzll_reload_tries_pr_channel_counter();
01257 gzll_timeout_counter = 0;
01258 gzll_try_counter = 0;
01259 GZLL_RFCE_PULSE();
01260 }
01261 }
01262 #endif
01263 }
01264
01265
01266
01267
01268 #ifndef GZLL_HOST_ONLY
01269 if(status & (1<<MAX_RT))
01270 {
01271 GZLL_RFCE_LOW();
01272
01273 gzll_timeout_counter += tries;
01274 temp = gzll_dyn_params[GZLL_PARAM_TX_TIMEOUT];
01275
01276
01277 if((temp != 0 && gzll_timeout_counter >= temp) ||
01278 gzll_pending_goto_idle)
01279 {
01280 gzll_set_system_idle();
01281 }
01282 else
01283 {
01284
01285 if(gzll_tries_pr_channel_counter == 0)
01286 {
01287
01288 if(gzll_channel_switch_counter > gzll_dyn_params[GZLL_PARAM_COLLISION_CHANNEL_SWITCH_LIMIT])
01289 {
01290 gzll_sync_period = 0;
01291 gzll_sync_on = false;
01292 gzll_start_new_tx(GZLL_CHANNEL_RANDOM);
01293 }
01294 else
01295 {
01296 if(gzll_sync_on)
01297 {
01298
01299 if(gzll_chm_get_tx_ce_offset() > 1)
01300 {
01301 gzll_radio_active_f = false;
01302 }
01303 gzll_start_new_tx(GZLL_CHANNEL_ESTIMATED);
01304 }
01305 else
01306 {
01307 gzll_start_new_tx(GZLL_CHANNEL_NEXT_INDEX);
01308 }
01309 }
01310 }
01311 else
01312 {
01313 gzll_set_radio_auto_retries();
01314 GZLL_RFCE_PULSE();
01315 }
01316 }
01317 }
01318 #endif
01319
01320 GZLL_RFCK_DISABLE();
01321 GZLL_INTERRUPTS_ENABLE();
01322 }
01323
01324 void gzll_timer_isr_function(void)
01325 {
01326 uint16_t temp;
01327
01328 GZLL_INTERRUPTS_DISABLE();
01329 gzll_chm_execute();
01330
01331
01332 #ifndef GZLL_HOST_ONLY
01333 if(gzll_timer_period_modified == 1)
01334 {
01335 gzll_set_timer_period(gzll_dyn_params[GZLL_PARAM_RX_PERIOD]);
01336 gzll_timer_period_modified = 0;
01337 }
01338 #endif
01339
01340
01341 #ifndef GZLL_DEVICE_ONLY
01342 if(gzll_state_var == GZLL_HOST_ACTIVE)
01343 {
01344 temp = gzll_chm_get_current_rx_channel();
01345 GZLL_RFCK_ENABLE();
01346
01347
01348 if(temp != gzll_channel_tab_index)
01349 {
01350 GZLL_RFCE_LOW();
01351 hal_nrf_set_rf_channel(gzll_channel_tab[temp]);
01352 GZLL_RFCE_HIGH();
01353 gzll_channel_tab_index = temp;
01354 }
01355
01356 temp = gzll_chm_get_rx_ce_offset();
01357
01358
01359 if(gzll_chm_get_rx_ce_offset() == 0)
01360 {
01361 gzll_set_radio_power_on(true);
01362 gzll_radio_active_f = true;
01363 GZLL_RFCE_HIGH();
01364 }
01365 else
01366 {
01367 GZLL_RFCE_LOW();
01368 gzll_radio_active_f = false;
01369 gzll_set_radio_power_on(false);
01370 }
01371
01372 gzll_timeout_counter++;
01373
01374 temp = gzll_dyn_params[GZLL_PARAM_RX_TIMEOUT];
01375 if(gzll_dyn_params[GZLL_PARAM_RX_TIMEOUT] > 0 && (gzll_timeout_counter >= temp))
01376 {
01377 gzll_set_system_idle();
01378 }
01379 }
01380 else
01381 #endif
01382 {
01383
01384 #ifndef GZLL_HOST_ONLY
01385 if(gzll_state_var == GZLL_DEVICE_ACTIVE)
01386 {
01387
01388 if(gzll_pending_tx_start)
01389 {
01390 temp = gzll_chm_get_tx_ce_offset();
01391
01392 if( !gzll_sync_on ||
01393 (temp == 0 && (gzll_channel_tab_index == gzll_chm_get_current_rx_channel()))
01394 )
01395 {
01396 GZLL_RFCE_PULSE();
01397 gzll_radio_active_f = true;
01398 gzll_pending_tx_start = 0;
01399 }
01400 }
01401 }
01402 #endif
01403 }
01404
01405 #ifndef GZLL_HOST_ONLY
01406 if(gzll_sync_period > 0)
01407 {
01408 gzll_sync_period--;
01409 }
01410 else
01411 {
01412 gzll_sync_on = false;
01413 }
01414 #endif
01415
01416 GZLL_RFCK_DISABLE();
01417 GZLL_INTERRUPTS_ENABLE();
01418 }
01419
01420
01421
01422
01423
01424 static xdata uint8_t gzll_chm_rx_channel_index = 0;
01425 static xdata uint8_t gzll_chm_hold_rx_channel_index = 0;
01426 static xdata uint16_t gzll_chm_rx_channel_hold = 0;
01427 static xdata uint16_t gzll_chm_rx_mode1_sequence = 0;
01428
01429 static void gzll_chm_execute()
01430 {
01431 if(gzll_chm_rx_channel_hold > 0)
01432 {
01433 gzll_chm_rx_channel_hold--;
01434 };
01435
01436
01437 gzll_chm_rx_mode1_sequence = (gzll_chm_rx_mode1_sequence + 1) % gzll_dyn_params[GZLL_PARAM_HOST_MODE_1_CYCLE_PERIOD];
01438
01439 if( (gzll_dyn_params[GZLL_PARAM_HOST_MODE] == GZLL_HOST_MODE_0) ||
01440 (gzll_chm_rx_mode1_sequence == 0))
01441 {
01442 gzll_chm_rx_channel_index = (gzll_chm_rx_channel_index + 1) % gzll_channel_tab_size;
01443 }
01444 }
01445
01446 static void gzll_chm_reset_rx_channel_index()
01447 {
01448 gzll_chm_rx_channel_index = gzll_channel_tab_index;
01449 gzll_chm_rx_mode1_sequence = 0;
01450 }
01451
01452 static uint8_t gzll_chm_get_next_rx_channel()
01453 {
01454 if(gzll_chm_rx_channel_hold > 1)
01455 {
01456 return gzll_chm_hold_rx_channel_index;
01457 }
01458 else
01459 {
01460 return (gzll_chm_rx_channel_index + 1) % gzll_channel_tab_size;
01461 }
01462 }
01463
01464 static uint8_t gzll_chm_get_current_rx_channel()
01465 {
01466 if(gzll_chm_rx_channel_hold > 0)
01467 {
01468 return gzll_chm_hold_rx_channel_index;
01469 }
01470 else
01471 {
01472 return gzll_chm_rx_channel_index;
01473 }
01474 }
01475
01476 static void gzll_chm_hold_rx_channel()
01477 {
01478 gzll_chm_rx_channel_hold = gzll_dyn_params[GZLL_PARAM_RX_CHANNEL_HOLD_PERIODS];
01479 gzll_chm_hold_rx_channel_index = gzll_channel_tab_index;
01480 }
01481
01482 static uint16_t gzll_chm_get_tx_ce_offset()
01483 {
01484 if((gzll_dyn_params[GZLL_PARAM_HOST_MODE] == GZLL_HOST_MODE_0) || (gzll_chm_rx_channel_hold > 0))
01485 {
01486 return 0;
01487 }
01488
01489 else
01490 {
01491 if(gzll_chm_rx_mode1_sequence == 0)
01492 {
01493 return 0;
01494 }
01495 else
01496 {
01497 return (gzll_dyn_params[GZLL_PARAM_HOST_MODE_1_CYCLE_PERIOD] - gzll_chm_rx_mode1_sequence);
01498 }
01499 }
01500 }
01501
01502 static uint16_t gzll_chm_get_rx_ce_offset()
01503 {
01504 uint16_t total_tx_time_per_channel;
01505 uint16_t rx_periods_per_channel;
01506
01507 if(gzll_dyn_params[GZLL_PARAM_HOST_MODE] == GZLL_HOST_MODE_0 || (gzll_chm_rx_channel_hold > 0))
01508 {
01509 return 0;
01510 }
01511 else
01512 {
01513 if(gzll_chm_rx_mode1_sequence == 0)
01514 {
01515 return 0;
01516 }
01517 else
01518 {
01519 total_tx_time_per_channel = gzll_dyn_params[GZLL_PARAM_TX_ATTEMPTS_PR_CHANNEL_WHEN_SYNC_OFF] * GZLL_TYP_TX_PERIOD;
01520 rx_periods_per_channel = total_tx_time_per_channel / gzll_dyn_params[GZLL_PARAM_RX_PERIOD];
01521
01522 if(gzll_chm_rx_mode1_sequence <= (gzll_channel_tab_size * rx_periods_per_channel))
01523 {
01524 return ((rx_periods_per_channel - (gzll_chm_rx_mode1_sequence % rx_periods_per_channel)) - 1);
01525 }
01526 else
01527 {
01528 return (gzll_dyn_params[GZLL_PARAM_HOST_MODE_1_CYCLE_PERIOD] - gzll_chm_rx_mode1_sequence);
01529 }
01530 }
01531 }
01532 }
01533
01534 static void gzll_set_radio_power_on(bool on)
01535 {
01536 uint8_t n;
01537
01538 if(on)
01539 {
01540 if(!gzll_power_on)
01541 {
01542 hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
01543 n = 3;
01544 while(n--) {}
01545 gzll_power_on = true;
01546 }
01547 }
01548 else
01549 {
01550 hal_nrf_set_power_mode(HAL_NRF_PWR_DOWN);
01551 gzll_power_on = false;
01552 }
01553 }
01554