00001
00056
00057 #include "at86rf230_registermap.h"
00058
00059 #include "compiler.h"
00060 #include "hal.h"
00061
00062
00063
00064
00065
00066
00067
00068
00069 #define HAL_DUMMY_READ ( 0x00 )
00070
00071 #define HAL_TRX_CMD_RW ( 0xC0 )
00072 #define HAL_TRX_CMD_RR ( 0x80 )
00073 #define HAL_TRX_CMD_FW ( 0x60 )
00074 #define HAL_TRX_CMD_FR ( 0x20 )
00075 #define HAL_TRX_CMD_SW ( 0x40 )
00076 #define HAL_TRX_CMD_SR ( 0x00 )
00077 #define HAL_TRX_CMD_RADDRM ( 0x7F )
00078
00079 #define HAL_CALCULATED_CRC_OK ( 0 )
00080
00081
00093 static uint16_t hal_system_time;
00094
00095
00096 static uint8_t volatile hal_bat_low_flag;
00097 static uint8_t volatile hal_trx_ur_flag;
00098 static uint8_t volatile hal_trx_end_flag;
00099 static uint8_t volatile hal_rx_start_flag;
00100 static uint8_t volatile hal_unknown_isr_flag;
00101 static uint8_t volatile hal_pll_unlock_flag;
00102 static uint8_t volatile hal_pll_lock_flag;
00103
00104
00105
00117 static hal_trx_isr_event_handler_t rx_start_callback;
00118
00130 static hal_trx_isr_event_handler_t trx_end_callback;
00131
00132
00133
00138 void hal_init( void ){
00139
00140
00141 hal_system_time = 0;
00142 hal_reset_flags( );
00143
00144
00145 DDR_SLP_TR |= (1 << SLP_TR);
00146 DDR_RST |= (1 << RST);
00147
00148
00149
00150 HAL_DDR_SPI |= (1 << HAL_DD_SS) | (1 << HAL_DD_SCK) | (1 << HAL_DD_MOSI);
00151 HAL_PORT_SPI |= (1 << HAL_DD_SS) | (1 << HAL_DD_SCK);
00152 SPCR = (1 << SPE) | (1 << MSTR);
00153 SPSR = (1 << SPI2X);
00154
00155
00156 TCCR1B = HAL_TCCR1B_CONFIG;
00157 TIFR1 |= (1 << ICF1);
00158 HAL_ENABLE_OVERFLOW_INTERRUPT( );
00159 hal_enable_trx_interrupt( );
00160 }
00161
00167 void hal_reset_flags( void ){
00168
00169 AVR_ENTER_CRITICAL_REGION( );
00170
00171
00172 hal_bat_low_flag = 0;
00173 hal_trx_ur_flag = 0;
00174 hal_trx_end_flag = 0;
00175 hal_rx_start_flag = 0;
00176 hal_unknown_isr_flag = 0;
00177 hal_pll_unlock_flag = 0;
00178 hal_pll_lock_flag = 0;
00179
00180
00181 rx_start_callback = NULL;
00182 trx_end_callback = NULL;
00183
00184 AVR_LEAVE_CRITICAL_REGION( )
00185 }
00186
00195 uint8_t hal_get_bat_low_flag( void ){
00196 return hal_bat_low_flag;
00197 }
00198
00203 void hal_clear_bat_low_flag( void ){
00204
00205 AVR_ENTER_CRITICAL_REGION( );
00206 hal_bat_low_flag = 0;
00207 AVR_LEAVE_CRITICAL_REGION( );
00208 }
00209
00218 uint8_t hal_get_trx_ur_flag( void ){
00219 return hal_trx_ur_flag;
00220 }
00221
00226 void hal_clear_trx_ur_flag( void ){
00227
00228 AVR_ENTER_CRITICAL_REGION( );
00229 hal_trx_ur_flag = 0;
00230 AVR_LEAVE_CRITICAL_REGION( );
00231 }
00232
00241 uint8_t hal_get_trx_end_flag( void ){
00242 return hal_trx_end_flag;
00243 }
00244
00249 void hal_clear_trx_end_flag( void ){
00250
00251 AVR_ENTER_CRITICAL_REGION( );
00252 hal_trx_end_flag = 0;
00253 AVR_LEAVE_CRITICAL_REGION( );
00254 }
00255
00261 void hal_set_trx_end_event_handler( hal_trx_isr_event_handler_t trx_end_callback_handle ){
00262
00263 AVR_ENTER_CRITICAL_REGION( );
00264 trx_end_callback = trx_end_callback_handle;
00265 AVR_LEAVE_CRITICAL_REGION( );
00266 }
00267
00272 void hal_clear_trx_end_event_handler( void ){
00273
00274 AVR_ENTER_CRITICAL_REGION( );
00275 trx_end_callback = NULL;
00276 AVR_LEAVE_CRITICAL_REGION( );
00277 }
00278
00287 uint8_t hal_get_rx_start_flag( void ){
00288 return hal_rx_start_flag;
00289 }
00290
00295 void hal_clear_rx_start_flag( void ){
00296
00297 AVR_ENTER_CRITICAL_REGION( );
00298 hal_rx_start_flag = 0;
00299 AVR_LEAVE_CRITICAL_REGION( );
00300 }
00301
00307 void hal_set_rx_start_event_handler( hal_trx_isr_event_handler_t rx_start_callback_handle ){
00308
00309 AVR_ENTER_CRITICAL_REGION( );
00310 rx_start_callback = rx_start_callback_handle;
00311 AVR_LEAVE_CRITICAL_REGION( );
00312 }
00313
00318 void hal_clear_rx_start_event_handler( void ){
00319
00320 AVR_ENTER_CRITICAL_REGION( );
00321 rx_start_callback = NULL;
00322 AVR_LEAVE_CRITICAL_REGION( );
00323 }
00324
00333 uint8_t hal_get_unknown_isr_flag( void ){
00334 return hal_unknown_isr_flag;
00335 }
00336
00341 void hal_clear_unknown_isr_flag( void ){
00342
00343 AVR_ENTER_CRITICAL_REGION( );
00344 hal_unknown_isr_flag = 0;
00345 AVR_LEAVE_CRITICAL_REGION( );
00346 }
00347
00356 uint8_t hal_get_pll_unlock_flag( void ){
00357 return hal_pll_unlock_flag;
00358 }
00359
00364 void hal_clear_pll_unlock_flag( void ){
00365
00366 AVR_ENTER_CRITICAL_REGION( );
00367 hal_pll_unlock_flag = 0;
00368 AVR_LEAVE_CRITICAL_REGION( );
00369 }
00370
00379 uint8_t hal_get_pll_lock_flag( void ){
00380 return hal_pll_lock_flag;
00381 }
00382
00387 void hal_clear_pll_lock_flag( void ){
00388
00389 AVR_ENTER_CRITICAL_REGION( );
00390 hal_pll_lock_flag = 0;
00391 AVR_LEAVE_CRITICAL_REGION( );
00392 }
00393
00405 uint8_t hal_register_read( uint8_t address ){
00406
00407
00408 address &= HAL_TRX_CMD_RADDRM;
00409 address |= HAL_TRX_CMD_RR;
00410
00411 AVR_ENTER_CRITICAL_REGION( );
00412
00413 HAL_SS_LOW( );
00414
00415
00416 SPDR = address;
00417 while ((SPSR & (1 << SPIF)) == 0) {;}
00418 uint8_t register_value = SPDR;
00419
00420 SPDR = HAL_DUMMY_READ;
00421 while ((SPSR & (1 << SPIF)) == 0) {;}
00422 register_value = SPDR;
00423
00424 HAL_SS_HIGH( );
00425
00426 AVR_LEAVE_CRITICAL_REGION( );
00427
00428 return register_value;
00429 }
00430
00441 void hal_register_write( uint8_t address, uint8_t value ){
00442
00443
00444 address = HAL_TRX_CMD_RW | (HAL_TRX_CMD_RADDRM & address);
00445
00446 AVR_ENTER_CRITICAL_REGION( );
00447
00448 HAL_SS_LOW( );
00449
00450
00451 SPDR = address;
00452 while ((SPSR & (1 << SPIF)) == 0) {;}
00453 uint8_t dummy_read = SPDR;
00454
00455 SPDR = value;
00456 while ((SPSR & (1 << SPIF)) == 0) {;}
00457 dummy_read = SPDR;
00458
00459 HAL_SS_HIGH( );
00460
00461 AVR_LEAVE_CRITICAL_REGION( );
00462 }
00463
00476 uint8_t hal_subregister_read( uint8_t address, uint8_t mask, uint8_t position ){
00477
00478
00479 uint8_t register_value = hal_register_read( address );
00480 register_value &= mask;
00481 register_value >>= position;
00482
00483 return register_value;
00484 }
00485
00499 void hal_subregister_write( uint8_t address, uint8_t mask, uint8_t position,
00500 uint8_t value ){
00501
00502
00503 uint8_t register_value = hal_register_read( address );
00504 register_value &= ~mask;
00505
00506
00507 value <<= position;
00508 value &= mask;
00509
00510 value |= register_value;
00511
00512
00513 hal_register_write( address, value );
00514 }
00515
00527 __z void hal_frame_read( hal_rx_frame_t *rx_frame ){
00528
00529 AVR_ENTER_CRITICAL_REGION( );
00530
00531 HAL_SS_LOW( );
00532
00533
00534 SPDR = HAL_TRX_CMD_FR;
00535 while ((SPSR & (1 << SPIF)) == 0) {;}
00536 uint8_t frame_length = SPDR;
00537
00538
00539 SPDR = HAL_DUMMY_READ;
00540 while ((SPSR & (1 << SPIF)) == 0) {;}
00541 frame_length = SPDR;
00542
00543
00544 if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)) {
00545
00546
00547 uint16_t crc = 0;
00548 uint8_t *rx_data = (rx_frame->data);
00549
00550 rx_frame->length = frame_length;
00551
00552
00553 do {
00554
00555 SPDR = HAL_DUMMY_READ;
00556 while ((SPSR & (1 << SPIF)) == 0) {;}
00557 *rx_data = SPDR;
00558 crc = crc_ccitt_update( crc, *rx_data++ );
00559 } while (--frame_length > 0);
00560
00561
00562 SPDR = HAL_DUMMY_READ;
00563 while ((SPSR & (1 << SPIF)) == 0) {;}
00564 rx_frame->lqi = SPDR;
00565
00566 HAL_SS_HIGH( );
00567
00568
00569 if (crc == HAL_CALCULATED_CRC_OK) {
00570 rx_frame->crc = true;
00571 } else { rx_frame->crc = false; }
00572 } else {
00573
00574 rx_frame->length = 0;
00575 rx_frame->lqi = 0;
00576 rx_frame->crc = false;
00577
00578 HAL_SS_HIGH( );
00579 }
00580
00581 AVR_LEAVE_CRITICAL_REGION( );
00582 }
00583
00592 __z void hal_frame_write( uint8_t *write_buffer, uint8_t length ){
00593
00594 length &= HAL_TRX_CMD_RADDRM;
00595
00596 AVR_ENTER_CRITICAL_REGION( );
00597
00598 HAL_SS_LOW( );
00599
00600
00601 SPDR = HAL_TRX_CMD_FW;
00602 while ((SPSR & (1 << SPIF)) == 0) {;}
00603 uint8_t dummy_read = SPDR;
00604
00605 SPDR = length;
00606 while ((SPSR & (1 << SPIF)) == 0) {;}
00607 dummy_read = SPDR;
00608
00609
00610 do {
00611
00612 SPDR = *write_buffer++;
00613 while ((SPSR & (1 << SPIF)) == 0) {;}
00614 dummy_read = SPDR;
00615 } while (--length > 0);
00616
00617 HAL_SS_HIGH( );
00618
00619 AVR_LEAVE_CRITICAL_REGION( );
00620 }
00621
00632 __z void hal_sram_read( uint8_t address, uint8_t length, uint8_t *data ){
00633
00634 AVR_ENTER_CRITICAL_REGION( );
00635
00636 HAL_SS_LOW( );
00637
00638
00639 SPDR = HAL_TRX_CMD_SR;
00640 while ((SPSR & (1 << SPIF)) == 0) {;}
00641 uint8_t dummy_read = SPDR;
00642
00643
00644 SPDR = address;
00645 while ((SPSR & (1 << SPIF)) == 0) {;}
00646 dummy_read = SPDR;
00647
00648
00649 do {
00650
00651 SPDR = HAL_DUMMY_READ;
00652 while ((SPSR & (1 << SPIF)) == 0) {;}
00653 *data++ = SPDR;
00654 } while (--length > 0);
00655
00656 HAL_SS_HIGH( );
00657
00658 AVR_LEAVE_CRITICAL_REGION( );
00659 }
00660
00671 __z void hal_sram_write( uint8_t address, uint8_t length, uint8_t *data ){
00672
00673 AVR_ENTER_CRITICAL_REGION( );
00674
00675 HAL_SS_LOW( );
00676
00677
00678 SPDR = HAL_TRX_CMD_SW;
00679 while ((SPSR & (1 << SPIF)) == 0) {;}
00680 uint8_t dummy_read = SPDR;
00681
00682
00683 SPDR = address;
00684 while ((SPSR & (1 << SPIF)) == 0) {;}
00685 dummy_read = SPDR;
00686
00687
00688 do {
00689
00690 SPDR = *data++;
00691 while ((SPSR & (1 << SPIF)) == 0) {;}
00692 dummy_read = SPDR;
00693 } while (--length > 0);
00694
00695 HAL_SS_HIGH( );
00696
00697 AVR_LEAVE_CRITICAL_REGION( );
00698 }
00699
00707 uint32_t hal_get_system_time( void ){
00708
00709 uint32_t system_time = hal_system_time;
00710 system_time <<= 16;
00711
00712
00713
00714 AVR_ENTER_CRITICAL_REGION( );
00715
00716 system_time |= TCNT1;
00717
00718 AVR_LEAVE_CRITICAL_REGION( );
00719
00720
00721 return ((system_time / HAL_US_PER_SYMBOL) & HAL_SYMBOL_MASK);
00722 }
00723
00724
00725
00726 #if defined( DOXYGEN )
00727
00731 void TIMER1_CAPT_vect( void );
00732 #else
00733 ISR( TIMER1_CAPT_vect ){
00734
00735
00736 uint32_t isr_timestamp = hal_system_time;
00737 isr_timestamp <<= 16;
00738 isr_timestamp |= TCNT1;
00739 isr_timestamp /= HAL_US_PER_SYMBOL;
00740 isr_timestamp &= HAL_SYMBOL_MASK;
00741
00742
00743 HAL_SS_LOW( );
00744
00745
00746 SPDR = RG_IRQ_STATUS | HAL_TRX_CMD_RR;
00747 while ((SPSR & (1 << SPIF)) == 0) {;}
00748 uint8_t register_value = SPDR;
00749
00750 SPDR = HAL_DUMMY_READ;
00751 while ((SPSR & (1 << SPIF)) == 0) {;}
00752 uint8_t interrupt_source = SPDR;
00753
00754 HAL_SS_HIGH( );
00755
00756
00757 if ((interrupt_source & HAL_RX_START_MASK)) {
00758
00759 hal_rx_start_flag++;
00760
00761 if( rx_start_callback != NULL ){
00762
00763
00764 HAL_SS_LOW( );
00765
00766 SPDR = HAL_TRX_CMD_FR;
00767 while ((SPSR & (1 << SPIF)) == 0) {;}
00768 uint8_t dummy_read = SPDR;
00769
00770 SPDR = HAL_DUMMY_READ;
00771 while ((SPSR & (1 << SPIF)) == 0) {;}
00772 uint8_t frame_length = SPDR;
00773
00774 HAL_SS_HIGH( );
00775
00776 rx_start_callback( isr_timestamp, frame_length );
00777 }
00778 } else if (interrupt_source & HAL_TRX_END_MASK) {
00779
00780 hal_trx_end_flag++;
00781
00782 if( trx_end_callback != NULL ){
00783
00784
00785 HAL_SS_LOW( );
00786
00787 SPDR = HAL_TRX_CMD_FR;
00788 while ((SPSR & (1 << SPIF)) == 0) {;}
00789 uint8_t dummy_read = SPDR;
00790
00791 SPDR = HAL_DUMMY_READ;
00792 while ((SPSR & (1 << SPIF)) == 0) {;}
00793 uint8_t frame_length = SPDR;
00794
00795 HAL_SS_HIGH( );
00796
00797 trx_end_callback( isr_timestamp, frame_length );
00798 }
00799 } else if (interrupt_source & HAL_TRX_UR_MASK) {
00800 hal_trx_ur_flag++;
00801 } else if (interrupt_source & HAL_PLL_UNLOCK_MASK) {
00802 hal_pll_unlock_flag++;
00803 } else if (interrupt_source & HAL_PLL_LOCK_MASK) {
00804 hal_pll_lock_flag++;
00805 } else if (interrupt_source & HAL_BAT_LOW_MASK) {
00806
00807
00808
00809
00810 uint8_t trx_isr_mask = hal_register_read( RG_IRQ_MASK );
00811 trx_isr_mask &= ~HAL_BAT_LOW_MASK;
00812 hal_register_write( RG_IRQ_MASK, trx_isr_mask );
00813 hal_bat_low_flag++;
00814 } else {
00815 hal_unknown_isr_flag++;
00816 }
00817 }
00818 # endif
00819
00820
00821
00822 #if defined( DOXYGEN )
00823
00826 void TIMER1_OVF_vect( void );
00827 #else
00828 ISR( TIMER1_OVF_vect ){
00829 hal_system_time++;
00830 }
00831 #endif
00832