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(); } }
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{ v=_bmac_channel_check(); rf_rx_off(); if(v==1) break; // 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); } rf_test_mode(); rf_carrier_on(); nrk_wait(_bmac_check_period); //nrk_wait_until_next_period(); rf_carrier_off(); rf_data_mode(); // send packet rf_rx_off(); pkt_got_ack=rf_tx_packet (&bmac_rfTxInfo); rf_rx_off(); tx_data_ready=0; nrk_event_signal (bmac_tx_pkt_done_signal); return NRK_OK; }
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 cmd_periodic(uint8_t argc, char **argv) { periodic_func_t **funcp; periodic_func_t *func = NULL; bool enable; int8_t rc; if (argc != 1 && argc < 3) { OUT("usage: periodic [<func> +|- [<args>...]]\r\n"); return NRK_ERROR; } funcp = &functions[0]; while (*funcp) { if (argc == 1) { OUTF((*funcp)->name); OUT(" "); } else { if (!strcmp_P(argv[1], (*funcp)->name)) break; } funcp++; } if (argc == 1) { OUT("\r\n"); return NRK_OK; } if (!*funcp) { OUT("ERROR: func not found\r\n"); return NRK_ERROR; } func = *funcp; enable = argv[2][0] == '+'; if (enable && func->config) { rc = func->config(argc - 3, argc >= 3 ? &argv[3] : NULL); if (rc != NRK_OK) { LOG("config failed: func "); LOGF(func->name); LOGNL(); return NRK_ERROR; } } func->enabled = enable; nrk_event_signal(func_signal); LOG("func enabled: "); LOGF(func->name); LOGP(" %d", func->enabled); LOGNL(); return NRK_OK; }
void nl_tx_task() { TransmitBuffer *ptr = NULL; // pointer to the buffer to be transmitted nrk_sig_t tx_done_signal; // to hold the tx_done signal from the link layer int8_t ret; // to hold the return value of various functions int8_t port_index; // to store the index of the corresponding port element int8_t sent; // to count the number of times the HELLO msg was sent int8_t isApplication; // flag to indicate whether the packet in the transmit // buffer is an APPLICATION / NW_CONTROL packet nrk_time_t timeout; nrk_time_t start; // used for sending network control messages nrk_time_t end; nrk_time_t elapsed; // wait for the nl_rx_task to start bmac while(!bmac_started()) nrk_wait_until_next_period(); // retrieve and register for the 'transmit done' signal from bmac tx_done_signal = bmac_get_tx_done_signal(); if( nrk_signal_register(tx_done_signal) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error while registering for the bmax_tx_done_signal\r\n")); } // initialise the timer nrk_time_get(&start); end.secs = start.secs; end.nano_secs = start.nano_secs; sent = 0; // set the radio power if( bmac_set_rf_power(10) == NRK_ERROR) { nrk_led_set(RED_LED); nrk_int_disable(); while(1) nrk_kprintf(PSTR("Error setting the transmit power\r\n")); } while(1) { isApplication = FALSE; // assume at the beginning that a nw_ctrl pkt will be transmitted ret = nrk_time_sub(&elapsed, end, start); if(ret == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_time_sub\r\n")); } nrk_time_compact_nanos(&elapsed); if(elapsed.secs >= HELLO_PERIOD) { sent++; build_Msg_Hello(&mhe); // build the 'HELLO' message if(DEBUG_NL == 2) { nrk_kprintf(PSTR("After building Msg_Hello, packet = ")); print_pkt(&pkt_tx); } enter_cr(bm_sem, 34); ret = insert_tx_aq(&pkt_tx); // insert it into the transmit queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("build_Msg_Hello() inserted packet.")); print_tx_buffer(); //print_pkt_header(&pkt_tx); } if(ret == NRK_ERROR && DEBUG_NL == 2) { nrk_kprintf(PSTR("HELLO msg was not inserted into the transmit queue\r\n")); } start.secs = end.secs; start.nano_secs = end.nano_secs; // reinitialise the timer } if(sent >= 3) //NGB_LIST_PERIOD / HELLO_PERIOD) // NGB_LIST period is always a multiple of HELLO_PERIOD { build_Msg_NgbList(&mn); // build the 'NGB_LIST' message enter_cr(bm_sem, 34); ret = insert_tx_aq(&pkt_tx); // insert it into the transmit queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("build_Msg_NgbList() inserted packet.")); print_tx_buffer(); //print_pkt_header(&pkt_tx); } if(ret == NRK_ERROR && DEBUG_NL == 2) { nrk_kprintf(PSTR("NGB_LIST msg was not inserted into the transmit queue\r\n")); } sent = 0; // reset the value of 'sent' } if(rand() % 2 == 0) // random number generator collect_queue_statistics(); enter_cr(bm_sem, 34); ptr = remove_tx_aq(); leave_cr(bm_sem, 34); if(ptr == NULL) // transmit queue is empty { if(DEBUG_NL == 2) nrk_kprintf(PSTR("NL:Transmit queue is empty\r\n")); // update the end time nrk_time_get(&end); nrk_wait_until_next_period(); // FIX ME continue; } if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Packet removed. Packet = ")); //print_pkt_header( &(ptr -> pkt) ); print_pkt( &(ptr -> pkt) ); //print_tx_buffer(); } // check to see the type of packet. It should be of type APPLICATION and be sent by this // node if( (pkt_type(&(ptr -> pkt)) == APPLICATION) && ((ptr -> pkt).src == NODE_ADDR) ) { // remove the encapsulated TL segment from the packet unpack_TL_UDP_header(&seg, (ptr -> pkt).data); memcpy(seg.data, (ptr -> pkt).data + SIZE_TRANSPORT_UDP_HEADER, MAX_APP_PAYLOAD); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Segment Removed = ")); print_seg(&seg); } isApplication = TRUE; } // pack the network packet header into the transmit buffer pack_NW_Packet_header(tx_buf, &(ptr -> pkt)); // append the network payload into the transmit buffer memcpy(tx_buf + SIZE_NW_PACKET_HEADER, (ptr -> pkt).data, MAX_NETWORK_PAYLOAD); enter_cr(bm_sem, 34); insert_tx_fq(ptr); // release the transmit buffer into the free queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Released transmit buffer back into queue\n")); print_tx_buffer(); } do { ret = bmac_tx_pkt_nonblocking(tx_buf, SIZE_NW_PACKET); // try to queue the buffer in link layer if(ret == NRK_ERROR) if(nrk_event_wait(SIG(tx_done_signal)) == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n")); } }while(ret == NRK_ERROR); // packet is queued at link layer timeout.secs = 10; // set a wait period of maximum 10 seconds timeout.nano_secs = 0; if( nrk_signal_register(nrk_wakeup_signal) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL:nl_tx(): Error registering for nrk_wakeup_signal\r\n")); } if( nrk_set_next_wakeup(timeout) == NRK_ERROR) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx(): Error returned by nrk_set_next_wakeup()\r\n")); } nrk_led_set(BLUE_LED); ret = nrk_event_wait (SIG(tx_done_signal) | SIG(nrk_wakeup_signal)); // wait for its transmission if(ret == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n")); } if(ret & SIG(tx_done_signal)) // bmac has successfully sent the packet over the radio { if(isApplication == TRUE) // it was an application layer packet { enter_cr(tl_sem, 34); port_index = port_to_port_index(seg.srcPort); if(port_index == NRK_ERROR) // sanity check { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in implementation of port element array\r\n")); } // signal 'send done' signal if(nrk_event_signal(ports[port_index].send_done_signal) == NRK_ERROR) { if(nrk_errno_get() == 1) // sanity check. This means signal was not created { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in creating signals in port element array\r\n")); } } leave_cr(tl_sem, 34); }// end if(isApplication == TRUE) else // a network control message was transmitted. Nothing to signal ; // do nothing } // end if(signal received = tx_done_signal) else if(ret & SIG(nrk_wakeup_signal)) { //nrk_led_set(RED_LED); //nrk_int_disable(); //while(1) //{ nrk_kprintf(PSTR("BMAC did not transmit the packet within specified time\r\n")); //} } else // unknown signal caught { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task(): Unknown signal caught\r\n")); } nrk_led_clr(BLUE_LED); // update the end time nrk_time_get(&end); } // end while(1) return; }
void process_app_pkt(NW_Packet *pkt, int8_t rssi) { int8_t ret; if(DEBUG_NL >= 1) { nrk_kprintf(PSTR("NL: process_app_pkt(): Entered\r\n")); nrk_kprintf(PSTR("NL process_app_pkt(): Received from ")); print_pkt_header(pkt); /* nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("What the hell am I doing here\r\n")); */ } if(tl_type(pkt -> type) == UDP) // the TL protocol is UDP { // unpack the UDP header unpack_TL_UDP_header(&udp_seg, pkt -> data); // copy the application payload into the data section of the UDP segment memcpy(udp_seg.data, pkt -> data + SIZE_TRANSPORT_UDP_HEADER, MAX_APP_PAYLOAD); // check to see if the destination port in the header is associated with any socket if(is_port_associated(udp_seg.destPort) == TRUE) // yes there is { int8_t port_index; enter_cr(bm_sem, 28); enter_cr(tl_sem, 28); if(DEBUG_NL == 2) { ; //nrk_kprintf(PSTR("NL: process_app_pkt(): Received segment = ")); //print_seg(&udp_seg); nrk_kprintf(PSTR("NL: process_app_pkt(): Before inserting into port queue\r\n")); } insert_rx_pq(&udp_seg, pkt -> prio, pkt -> src, rssi); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: process_app_pkt(): After inserting into port queue\r\n")); } port_index = port_to_port_index(udp_seg.destPort); // extract the relevant port element if(port_index == NRK_ERROR) //sanity check for debugging { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: process_app_pkt(): Bug detected in implementation of port/rbm element array\r\n")); } ret = nrk_event_signal(ports[port_index].data_arrived_signal); // signal 'data arrived' if(ret == NRK_ERROR) { if(nrk_errno_get() == 1) // this means the signal was not created. This is a bug { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: process_app_pkt(): Bug detected in implementation of port signals\r\n")); } } // end if(ret == NRK_ERROR) } // end if(is_port_associated()) else // if there is no socket associated with this port, simply drop the packet { if(DEBUG_NL == 0) { nrk_kprintf(PSTR("Unassociated port found: ")); printf("%u\n", udp_seg.destPort); } record_unassociated_socket_pkt(pkt); // record this fact } leave_cr(tl_sem, 28); leave_cr(bm_sem, 28); } // end if(tl_layer == UDP) else // as of now UDP is the only supported transport layer, hence print an error { nrk_kprintf(PSTR("NL: process_app_pkt(): Unsupported transport layer type detected = ")); printf("%d\r\n", pkt -> type); } return; }
void _isa_rx (uint8_t slot) { uint8_t n; uint32_t node_mask; volatile uint8_t timeout; #ifdef LED_DEBUG nrk_led_set(1); #endif rf_set_rx (&isa_rfRxInfo, isa_param.channel); // sets rx buffer and channel rf_polling_rx_on (); // Timing for waiting for sfd timeout = _nrk_os_timer_get(); timeout+=4; // 4ms n = 0; //nrk_gpio_set(NRK_DEBUG_3); while ((n = rf_rx_check_sfd()) == 0) { if (_nrk_os_timer_get() > timeout) { //spend too much time on waiting for a pkt's arrival rf_rx_off (); #ifdef LED_DEBUG nrk_led_clr(1); #endif #ifdef RX_DEBUG printf("sfd times out.\n\r"); #endif return; } } //printf("%d\n\r",_nrk_high_speed_timer_get()); // sfd received, start receiving packet and record start time rx_start_time = _nrk_high_speed_timer_get(); // Timing for waiting for finishing packet receiving timeout = _nrk_os_timer_get(); timeout += 5; // 5ms if (n != 0) { n = 0; //printf("Packet on its way\n\r"); while ((n = rf_polling_rx_packet (false,128)) == 0) { //printf("%d\n\r",_nrk_os_timer_get()); if (_nrk_os_timer_get () > timeout) { #ifdef RX_DEBUG printf("packet is too long, times out.\n\r"); #endif // spend too much time on receiving pkt. return; // huge timeout as fail safe } } } rf_rx_off (); if (n == 1) {// successfully received packet isa_rx_data_ready = 1; //potential problem: if repeater or recipient receives noise, the DHDR would be changed. And it is highly possible that the highest bit of DHDR would be set to 0 /*if(isa_node_mode != ISA_GATEWAY) DHDR = isa_rfRxInfo.pPayload[DHDR_INDEX];*/ #ifdef RX_DEBUG printf("Repeater slot = %d, local slot is %d.\n\r", isa_rfRxInfo.pPayload[SLOT_INDEX],global_slot); #endif RX_DEBUG nrk_event_signal(isa_rx_pkt_signal); //_nrk_high_speed_timer_reset(); //nrk_high_speed_timer_wait(0,CPU_PROCESS_TIME); //nrk_gpio_set(NRK_DEBUG_3); node_mask = ((uint32_t) 1) << isa_rfRxInfo.pPayload[SRC_INDEX]; if( !(node_mask & child_list)) return; //FIXME change // ACK required if(DHDR & (1<<7)){ // Transmit ACK packet DHR = configDHR(); isa_ack_buf[DHR_INDEX]= DHR; #ifdef ACK_DEBUG //printf("DHR is %d.\n\r",DHR); #endif isa_ack_tx.pPayload = isa_ack_buf; if (DHDR & (1<<2)){ // recipient , only reply explicit ACK //isa_ack_tx.length = PKT_DATA_START-1; isa_ack_tx.length = 2; } else { //reply ACK with time offsetX offsetX = rx_start_time - slot_start_time; //printf("slot_start_time is %d,rx_start_time is %d.\n\r",slot_start_time,rx_start_time); uint8_t temp1,temp2; temp1 = (offsetX & 0xFF00)>>8; isa_ack_buf[OFFSET_HIGH]=temp1; temp2 = (offsetX & 0x00FF); isa_ack_buf[OFFSET_LOW]=temp2; #ifdef ACK_DEBUG printf("offsetX is %d\n\r", offsetX); #endif //isa_ack_tx.length = PKT_DATA_START + 1; isa_ack_tx.length = 4; } rf_tx_tdma_packet (&isa_ack_tx,slot_start_time,isa_param.tx_guard_time,&tx_start_time); }
void bmac_enable() { is_enabled=1; rf_power_up(); nrk_event_signal (bmac_enable_signal); }
void tdma_enable () { tdma_is_enabled = 1; rf_power_up (); nrk_event_signal (tdma_enable_signal); }
void my_timer_callback() { int8_t v; nrk_led_toggle(GREEN_LED); nrk_gpio_toggle(NRK_DEBUG_0); // printf("#"); V_Awatt_S32R = ade_read32(AWATT); V_Avar_S32R = ade_read32(AVAR); memcpy(&V_TxBuff_U8R[V_WrPtr_U32R],&V_Awatt_S32R,3); V_WrPtr_U32R+=3; memcpy(&V_TxBuff_U8R[V_WrPtr_U32R],&V_Avar_S32R,3); V_WrPtr_U32R+=3; if(V_WrPtr_U32R == C_CircBuffSize) { V_WrPtr_U32R = 0; V_WrSeqNo_U8R = 1; } //////////////////////////// V_EvnDetCntr_U32R++; if(V_EvnDetCntr_U32R==Fs) { V_EvnDetCntr_U32R = 0; V_DataNew_U32R = V_Awatt_S32R; V_DiffData_S32R = V_DataNew_U32R - V_DataOld_U32R; V_DataOld_U32R = V_DataNew_U32R; if((V_DiffData_S32R>C_ThresholdPwr)||(V_DiffData_S32R<(-1*C_ThresholdPwr))) { F_Occ_U8R = 0; F_Det_U8R = 0; } else { if(F_Occ_U8R==0) { F_Det_U8R = 1; F_Occ_U8R = 1; } else F_Det_U8R = 0; } V_RdDSP_U16R = ade_read16(RUN); if(V_RdDSP_U16R==0) { ade_write16(RUN, START); printf("\r\n$$"); } } ///////////////////////////// if(F_ReadyForSignal_U8R==1) { if(((V_WrSeqNo_U8R*C_CircBuffSize + V_WrPtr_U32R)-(V_RdPtr_U32R)) >= C_SlipPktSize) { v = nrk_event_signal(signal_one); if(v==NRK_ERROR){} } } V_TINTcnt_U8R++; if(V_TINTcnt_U8R==250) { F_1secData_U8R = 1; V_TINTcnt_U8R=0; V_ArmsCurr_U32R = ade_read32(AIRMS); V_ArmsVolt_U32R = ade_read32(AVRMS); V_ArmsWatt_S32R = ade_read32(AWATT); } // nrk_kprintf( PSTR("*** Timer interrupt!\r\n")); }
static void discover_task () { uint8_t periods_in_idle = discover_period_s / DISCOVER_TASK_PERIOD_S; nrk_time_t now, elapsed; int8_t rc; while (1) { switch (discover_state) { case DISCOVER_IDLE: if (auto_discover) { if (periods_in_idle < periods_in_idle) break; set_state(DISCOVER_SCHEDULED); } break; case DISCOVER_SCHEDULED: #if ENABLE_LED pulse_led(led_discover); #endif set_state(DISCOVER_PENDING); nrk_event_signal(discover_signal); break; case DISCOVER_IN_PROGRESS: nrk_time_get(&now); nrk_time_sub(&elapsed, now, last_activity); if (time_cmp(&elapsed, &discover_time_out) < 0) { LOG("silent for "); LOGP("%lu ms\r\n", TIME_TO_MS(elapsed)); break; } LOG("finished, distrib routes: seq "); LOGP("%d\r\n", outstanding_seq); print_graph(&network); rc = calc_routes(&network, &routes); if (rc == NRK_OK) { print_routes(&routes); rc = broadcast_routes(&routes, outstanding_seq); if (rc != NRK_OK) LOG("WARN: failed to bcast routes\r\n"); } else { LOG("WARN: failed to calc routes\r\n"); } set_state(DISCOVER_COMPLETED); nrk_event_signal(discover_signal); break; case DISCOVER_PENDING: case DISCOVER_COMPLETED: /* the router failed to do its part in one task period */ set_state(DISCOVER_IDLE); break; default: ABORT("unexpected state\r\n"); } periods_in_state++; nrk_wait_until_next_period(); } ABORT("discover task exited\r\n"); }
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; }
void calc_power() { // FIXME: Disable interrupt later if power off to save energy // if(socket_0_active==0 && socket_1_active==0) return; // nrk_int_disable(); ADC_SET_CHANNEL (VOLTAGE_CHAN); nrk_spin_wait_us(ADC_SETUP_DELAY); ADC_SAMPLE_SINGLE(); ADC_GET_SAMPLE_10(v); ADC_SET_CHANNEL (CURRENT_LOW); nrk_spin_wait_us(ADC_SETUP_DELAY); ADC_SAMPLE_SINGLE(); ADC_GET_SAMPLE_10(c1); ADC_SET_CHANNEL (CURRENT_HIGH); nrk_spin_wait_us(ADC_SETUP_DELAY); ADC_SAMPLE_SINGLE(); ADC_GET_SAMPLE_10(c2); //ADC_SET_CHANNEL (5); //nrk_spin_wait_us(ADC_SETUP_DELAY); //ADC_SAMPLE_SINGLE(); //ADC_GET_SAMPLE_10(center_chan); //c1_center=(uint16_t)center_chan; // Catch the rising edge after the voltage dips below a low threshold // Then ignore that case until the voltage goes up again. // This filter is used to detect the zero crossing point //if(triggered==0 && v<VOLTAGE_LOW_THRESHOLD && v>v_last) //if(v>VOLTAGE_ZERO_THRESHOLD && v_last<=VOLTAGE_ZERO_THRESHOLD) if(v>v_center && v_last<=v_center) { //if(cycle_state==CYCLE_HIGH) cycle_state=CYCLE_LOW; //else { // Low to High transition cycle_state=CYCLE_HIGH; cycle_cnt++; if(energy_cycle<0) energy_cycle*=-1; energy_total+=energy_cycle; if(energy_cycle2<0) energy_cycle2*=-1; energy_total2+=energy_cycle2; energy_cycle=0; energy_cycle2=0; // } cycle_started=1; //triggered=1; } // Reset filter trap after the voltage goes up //if(v>VOLTAGE_ZERO_THRESHOLD) triggered=0; v_last=v; if(cycle_started==1) { ticks++; if(c1<c_p2p_low) c_p2p_low=c1; if(c1>c_p2p_high) c_p2p_high=c1; if(v<v_p2p_low) v_p2p_low=v; if(v>v_p2p_high) v_p2p_high=v; c1-=c_center; if(c2<c_p2p_low2) c_p2p_low2=c2; if(c2>c_p2p_high2) c_p2p_high2=c2; c2-=c2_center; // Do we need this? v-=v_center; // remove noise at floor //if(c1<10) c1=0; current_total+=((int32_t)c1*(int32_t)c1); voltage_total+=((int32_t)v*(int32_t)v); //if(cycle_state==CYCLE_LOW) v*=-1; energy_cycle+=((int32_t)c1*(int32_t)v); current_total2+=((int32_t)c2*(int32_t)c2); energy_cycle2+=((int32_t)c2*(int32_t)v); //printf( "c1=%u current=%lu\r\n",c1, current_total ); if(ticks>=2000) { // Save values to pass to event detector functions that calculate power for // packets etc freq=cycle_cnt; l_v_p2p_high=v_p2p_high; l_v_p2p_low=v_p2p_low; l_c_p2p_high=c_p2p_high; l_c_p2p_low=c_p2p_low; l_c_p2p_high2=c_p2p_high2; l_c_p2p_low2=c_p2p_low2; ticks_last=ticks; current_total_last=current_total; current_total2_last=current_total2; energy_total_last=energy_total; energy_total2_last=energy_total2; voltage_total_last=voltage_total; // Reset values for next cycle ticks=0; cycle_cnt=0; voltage_total=0; energy_total=0; energy_total2=0; current_total=0; current_total2=0; v_p2p_low=2000; v_p2p_high=0; c_p2p_low=2000; c_p2p_high=0; c_p2p_low2=2000; c_p2p_high2=0; // Signal event detector task nrk_event_signal(update_energy_sig); } } //nrk_int_enable(); }