void bmac_nw_task () { int8_t v; int8_t e; uint8_t backoff; nrk_sig_mask_t event; while(bmac_started()==0) nrk_wait_until_next_period(); //register the signal after bmac_init has been called v=nrk_signal_register(bmac_enable_signal); if(v==NRK_ERROR) nrk_kprintf( PSTR("Failed to register signal\r\n")); backoff=0; while (1) { #ifdef NRK_SW_WDT #ifdef BMAC_SW_WDT_ID nrk_sw_wdt_update(BMAC_SW_WDT_ID); #endif #endif if(is_enabled ) { v=1; if(rx_buf_empty==1) v=_bmac_channel_check(); // If the buffer is full, signal the receiving task again. else e=nrk_event_signal (bmac_rx_pkt_signal); // bmac_channel check turns on radio, don't turn off if // data is coming. if(v==0) { if(_bmac_rx()==1) { e=nrk_event_signal (bmac_rx_pkt_signal); //if(e==NRK_ERROR) { // nrk_kprintf( PSTR("bmac rx pkt signal failed\r\n")); // printf( "errno: %u \r\n",nrk_errno_get() ); //} } //else nrk_kprintf( PSTR("Pkt failed, buf could be corrupt\r\n" )); } if(/*rx_buf_empty==1 &&*/ tx_data_ready==1) { rf_rx_off(); _bmac_tx(); } //do { nrk_wait(_bmac_check_period); // if(rx_buf_empty!=1) nrk_event_signal (bmac_rx_pkt_signal); //} while(rx_buf_empty!=1); } else { event=0; do { v=nrk_signal_register(bmac_enable_signal); event=nrk_event_wait (SIG(bmac_enable_signal)); } while((event & SIG(bmac_enable_signal))==0); } //nrk_wait_until_next_period(); } }
void bmac_nw_task() { int8_t v; int8_t e; uint8_t backoff; nrk_sig_mask_t event; while(bmac_started() == 0) { nrk_wait_until_next_period(); } while(1) { if(is_enabled) { v = 1; rf_rx_on(); if(rx_buf_empty) { v = _bmac_channel_check(); } else { e = nrk_event_signal(bmac_rx_pkt_signal); // Mb // Should signal user task here as a "reminder" } if(v == 0) { // Channel detected as busy, attept to Rx _bmac_rx(); // Should signal user task here to notify of Rx } else if(tx_data_ready) { // Only try to Tx if the channel is free rf_rx_off(); // Mb _bmac_tx(); } //rf_rx_off(); // Mb nrk_wait(_bmac_check_period); } else { event =0; do { v = nrk_signal_register(bmac_enable_signal); event = nrk_event_wait(SIG(bmac_enable_signal)); } while((event & SIG(bmac_enable_signal))==0); } } }
int8_t _bmac_tx () { uint8_t v, backoff, backoff_count; uint16_t b; #ifdef DEBUG nrk_kprintf (PSTR ("_bmac_tx()\r\n")); #endif if (cca_active) { // Add random time here to stop nodes from synchronizing with eachother b = _nrk_time_to_ticks (&_bmac_check_period); b = b / ((rand () % 10) + 1); //printf( "waiting %d\r\n",b ); nrk_wait_until_ticks (b); //nrk_wait_ticks(b); backoff_count = 1; do { #ifdef BMAC_MOD_CCA v=_bmac_rx(); v=!v; if (v == 1) { break; } nrk_event_signal (bmac_rx_pkt_signal); #else v = _bmac_channel_check (); if (v == 1) break; #endif // Channel is busy backoff = rand () % (_b_pow (backoff_count)); #ifdef DEBUG printf ("backoff %d\r\n", backoff); #endif // printf( "backoff %d\r\n",backoff ); nrk_wait_until_next_n_periods (backoff); backoff_count++; if (backoff_count > 6) backoff_count = 6; // cap it at 64 b = _nrk_time_to_ticks (&_bmac_check_period); b = b / ((rand () % 10) + 1); // printf( "waiting %d\r\n",b ); nrk_wait_until_ticks (b); // nrk_wait_ticks(b); } while (v == 0); } // send extended preamble bmac_rfTxInfo.cca = 0; bmac_rfTxInfo.ackRequest = 0; uint16_t ms = _bmac_check_period.secs * 1000; ms += _bmac_check_period.nano_secs / 1000000; //printf( "CR ms: %u\n",ms ); //target_t.nano_secs+=20*NANOS_PER_MS; rf_rx_on (); pkt_got_ack = rf_tx_packet_repeat (&bmac_rfTxInfo, ms); // send packet // pkt_got_ack=rf_tx_packet (&bmac_rfTxInfo); rf_rx_off (); // Just in case auto-ack left radio on tx_data_ready = 0; nrk_event_signal (bmac_tx_pkt_done_signal); return NRK_OK; }