33
33
// Enable this flag to use channel traces
34
34
#define FHSS_CHANNEL_DEBUG
35
35
36
+ static void fhss_ws_update_uc_channel_callback (fhss_structure_t * fhss_structure );
37
+
36
38
fhss_structure_t * fhss_ws_enable (fhss_api_t * fhss_api , const fhss_ws_configuration_t * fhss_configuration , const fhss_timer_t * fhss_timer )
37
39
{
38
40
if (!fhss_api || !fhss_configuration || !fhss_timer ) {
@@ -50,22 +52,77 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
50
52
}
51
53
fhss_struct -> fhss_conf .fhss_ws_configuration = * fhss_configuration ;
52
54
fhss_struct -> number_of_channels = channel_count ;
53
-
54
55
return fhss_struct ;
55
56
}
56
57
58
+ static void fhss_ws_update_bc_channel (fhss_structure_t * fhss_structure )
59
+ {
60
+ uint8_t mac_address [8 ];
61
+ int32_t next_channel ;
62
+ fhss_structure -> callbacks .read_mac_address (fhss_structure -> fhss_api , mac_address );
63
+ if (fhss_structure -> ws -> channel_function == WS_FIXED_CHANNEL ) {
64
+
65
+ } else if (fhss_structure -> ws -> channel_function == WS_TR51CF ) {
66
+ next_channel = tr51_get_bc_channel_index (fhss_structure -> ws -> bc_slot , fhss_structure -> fhss_conf .fhss_ws_configuration .bsi , fhss_structure -> number_of_channels );
67
+ if (++ fhss_structure -> ws -> bc_slot == fhss_structure -> number_of_channels ) {
68
+ fhss_structure -> ws -> bc_slot = 0 ;
69
+ }
70
+ } else if (fhss_structure -> ws -> channel_function == WS_DH1CF ) {
71
+ next_channel = dh1cf_get_bc_channel_index (fhss_structure -> ws -> bc_slot , fhss_structure -> fhss_conf .fhss_ws_configuration .bsi , fhss_structure -> number_of_channels );
72
+ fhss_structure -> ws -> bc_slot ++ ;
73
+ } else if (fhss_structure -> ws -> channel_function == WS_VENDOR_DEF_CF ) {
74
+ //TODO: Callback to get channel schedule from application
75
+ }
76
+ #ifdef FHSS_CHANNEL_DEBUG
77
+ tr_info ("%" PRIu32 " BC %u %u" , fhss_structure -> platform_functions .fhss_get_timestamp (fhss_structure -> fhss_api ), next_channel , fhss_structure -> ws -> bc_slot );
78
+ #endif /*FHSS_CHANNEL_DEBUG*/
79
+ fhss_structure -> callbacks .change_channel (fhss_structure -> fhss_api , next_channel );
80
+ }
81
+
82
+ static void fhss_broadcast_handler (const fhss_api_t * fhss_api , uint16_t delay )
83
+ {
84
+ (void ) delay ;
85
+ fhss_structure_t * fhss_structure = fhss_get_object_with_api (fhss_api );
86
+ if (!fhss_structure ) {
87
+ return ;
88
+ }
89
+ if (fhss_structure -> ws -> is_on_bc_channel == false) {
90
+ fhss_start_timer (fhss_structure , fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_bc_dwell_interval * 1000 , fhss_broadcast_handler );
91
+ fhss_structure -> ws -> is_on_bc_channel = true;
92
+ fhss_ws_update_bc_channel (fhss_structure );
93
+ } else {
94
+ uint32_t timeout = (fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_broadcast_interval - fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_bc_dwell_interval ) * 1000 ;
95
+ fhss_start_timer (fhss_structure , timeout , fhss_broadcast_handler );
96
+ fhss_structure -> ws -> is_on_bc_channel = false;
97
+ // Should return to own (unicast) listening channel after broadcast channel
98
+ fhss_structure -> callbacks .change_channel (fhss_structure -> fhss_api , fhss_structure -> rx_channel );
99
+ #ifdef FHSS_CHANNEL_DEBUG
100
+ tr_info ("%" PRIu32 " UC %u" , fhss_structure -> platform_functions .fhss_get_timestamp (fhss_structure -> fhss_api ), fhss_structure -> rx_channel );
101
+ #endif /*FHSS_CHANNEL_DEBUG*/
102
+ }
103
+ }
104
+
57
105
static uint32_t fhss_ws_get_sf_timeout_callback (fhss_structure_t * fhss_structure )
58
106
{
59
107
return fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_uc_dwell_interval * 1000 ;
60
108
}
61
109
62
110
static int fhss_ws_handle_state_set (fhss_structure_t * fhss_structure , fhss_states fhss_state , uint16_t pan_id )
63
111
{
64
- (void ) fhss_state ;
65
112
(void ) pan_id ;
66
- //TODO: Remove hard coded channel function
67
- fhss_structure -> ws -> channel_function = WS_TR51CF ;
68
- fhss_start_timer (fhss_structure , fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_uc_dwell_interval * 1000 , fhss_superframe_handler );
113
+ if (fhss_state == FHSS_SYNCHRONIZED ) {
114
+ uint32_t fhss_broadcast_interval = fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_broadcast_interval ;
115
+ uint8_t fhss_bc_dwell_interval = fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_bc_dwell_interval ;
116
+ // Start broadcast schedule when BC intervals are known
117
+ if (fhss_broadcast_interval && fhss_bc_dwell_interval ) {
118
+ fhss_broadcast_handler (fhss_structure -> fhss_api , 0 );
119
+ }
120
+ // Start unicast schedule
121
+ fhss_ws_update_uc_channel_callback (fhss_structure );
122
+ fhss_start_timer (fhss_structure , fhss_structure -> fhss_conf .fhss_ws_configuration .fhss_uc_dwell_interval * 1000 , fhss_superframe_handler );
123
+ }
124
+
125
+ fhss_structure -> fhss_state = fhss_state ;
69
126
return 0 ;
70
127
}
71
128
@@ -74,26 +131,30 @@ static void fhss_ws_superframe_callback(fhss_structure_t *fhss_structure)
74
131
(void ) fhss_structure ;
75
132
}
76
133
77
- static void fhss_ws_update_channel_callback (fhss_structure_t * fhss_structure )
134
+ static void fhss_ws_update_uc_channel_callback (fhss_structure_t * fhss_structure )
78
135
{
79
136
uint8_t mac_address [8 ];
80
137
int32_t next_channel ;
81
138
fhss_structure -> callbacks .read_mac_address (fhss_structure -> fhss_api , mac_address );
82
139
if (fhss_structure -> ws -> channel_function == WS_FIXED_CHANNEL ) {
83
140
84
141
} else if (fhss_structure -> ws -> channel_function == WS_TR51CF ) {
85
- next_channel = fhss_structure -> rx_channel = tr51_get_uc_channel_index (fhss_structure -> ws -> slot , mac_address , fhss_structure -> number_of_channels );
86
- if (++ fhss_structure -> ws -> slot == fhss_structure -> number_of_channels ) {
87
- fhss_structure -> ws -> slot = 0 ;
142
+ next_channel = fhss_structure -> rx_channel = tr51_get_uc_channel_index (fhss_structure -> ws -> uc_slot , mac_address , fhss_structure -> number_of_channels );
143
+ if (++ fhss_structure -> ws -> uc_slot == fhss_structure -> number_of_channels ) {
144
+ fhss_structure -> ws -> uc_slot = 0 ;
88
145
}
89
146
} else if (fhss_structure -> ws -> channel_function == WS_DH1CF ) {
90
- next_channel = fhss_structure -> rx_channel = dh1cf_get_uc_channel_index (fhss_structure -> ws -> slot , mac_address , fhss_structure -> number_of_channels );
91
- fhss_structure -> ws -> slot ++ ;
147
+ next_channel = fhss_structure -> rx_channel = dh1cf_get_uc_channel_index (fhss_structure -> ws -> uc_slot , mac_address , fhss_structure -> number_of_channels );
148
+ fhss_structure -> ws -> uc_slot ++ ;
92
149
} else if (fhss_structure -> ws -> channel_function == WS_VENDOR_DEF_CF ) {
93
150
//TODO: Callback to get channel schedule from application
94
151
}
152
+ // Do not switch unicast channel when broadcast channel is active.
153
+ if (fhss_structure -> ws -> is_on_bc_channel == true) {
154
+ return ;
155
+ }
95
156
#ifdef FHSS_CHANNEL_DEBUG
96
- tr_info ("%" PRIu32 " UC %u %u" , fhss_structure -> platform_functions .fhss_get_timestamp (fhss_structure -> fhss_api ), next_channel , fhss_structure -> ws -> slot );
157
+ tr_info ("%" PRIu32 " UC %u %u" , fhss_structure -> platform_functions .fhss_get_timestamp (fhss_structure -> fhss_api ), next_channel , fhss_structure -> ws -> uc_slot );
97
158
#endif /*FHSS_CHANNEL_DEBUG*/
98
159
fhss_structure -> callbacks .change_channel (fhss_structure -> fhss_api , next_channel );
99
160
}
@@ -112,7 +173,7 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
112
173
if (fhss_structure -> fhss_state == FHSS_SYNCHRONIZED ) {
113
174
int32_t tx_channel ;
114
175
//TODO: Compute destination slot using neighbour table
115
- uint16_t destination_slot = fhss_structure -> ws -> slot ;
176
+ uint16_t destination_slot = fhss_structure -> ws -> uc_slot ;
116
177
if (fhss_structure -> ws -> channel_function == WS_TR51CF ) {
117
178
tx_channel = tr51_get_uc_channel_index (destination_slot , destination_address , fhss_structure -> number_of_channels );
118
179
} else if (fhss_structure -> ws -> channel_function == WS_DH1CF ) {
@@ -156,7 +217,7 @@ int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)
156
217
fhss_structure -> fhss_api -> write_synch_info = & fhss_write_synch_info_cb ;
157
218
fhss_structure -> fhss_api -> init_callbacks = & fhss_init_callbacks_cb ;
158
219
// Set internal API
159
- fhss_structure -> update_channel = fhss_ws_update_channel_callback ;
220
+ fhss_structure -> update_channel = fhss_ws_update_uc_channel_callback ;
160
221
fhss_structure -> update_superframe = fhss_ws_superframe_callback ;
161
222
fhss_structure -> read_superframe_timeout = fhss_ws_get_sf_timeout_callback ;
162
223
fhss_structure -> handle_state_set = fhss_ws_handle_state_set ;
@@ -165,5 +226,6 @@ int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)
165
226
return -1 ;
166
227
}
167
228
memset (fhss_structure -> ws , 0 , sizeof (fhss_ws_t ));
229
+ fhss_structure -> ws -> channel_function = fhss_structure -> fhss_conf .fhss_ws_configuration .ws_channel_function ;
168
230
return 0 ;
169
231
}
0 commit comments