nrk_sig_t bmac_get_rx_pkt_signal() { nrk_signal_register(bmac_rx_pkt_signal); return(bmac_rx_pkt_signal); }
nrk_sig_t bmac_get_tx_done_signal() { nrk_signal_register(bmac_tx_pkt_done_signal); return(bmac_tx_pkt_done_signal); }
void tdma_nw_task () { int8_t v, i; uint16_t slot, tmp,sync; nrk_sig_mask_t event; do { nrk_wait_until_next_period (); } while (!tdma_started ()); _tdma_slot_time.nano_secs = TDMA_DEFAULT_SLOT_MS * NANOS_PER_MS; _tdma_slot_time.secs = 0; //register the signal after bmac_init has been called v = nrk_signal_register (tdma_enable_signal); if (v == NRK_ERROR) nrk_kprintf (PSTR ("Failed to register signal\r\n")); slot = 0; //rf_set_rx (&tdma_rfRxInfo, tdma_chan); while (1) { if (tdma_mode == TDMA_HOST) { sync_status=1; // HOST is always synced // This is the downstream transmit slot if (slot == 0) { //rf_rx_off(); // If there is no pending packet, lets make an empty one if (tx_data_ready == 0) { tdma_rfTxInfo.pPayload = tdma_tx_buf; // Setup the header data tdma_rfTxInfo.pPayload[TDMA_DST_LOW] = 0xff; // dst tdma_rfTxInfo.pPayload[TDMA_DST_HIGH] = 0xff; tdma_rfTxInfo.pPayload[TDMA_SRC_LOW] = 0x00; // src tdma_rfTxInfo.pPayload[TDMA_SRC_HIGH] = 0x00; tdma_rfTxInfo.pPayload[TDMA_SEQ_NUM_LOW] = 0x00; // seq num tdma_rfTxInfo.pPayload[TDMA_SEQ_NUM_HIGH] = 0x00; tdma_rfTxInfo.length = TDMA_PCF_HEADER; } tdma_rfTxInfo.pPayload[TDMA_CYCLE_SIZE_LOW] = tdma_slots_per_cycle & 0xff; // cycle size tdma_rfTxInfo.pPayload[TDMA_CYCLE_SIZE_HIGH] = tdma_slots_per_cycle >> 8; tdma_rfTxInfo.pPayload[TDMA_SLOT_LOW] = 0; // slot tdma_rfTxInfo.pPayload[TDMA_SLOT_HIGH] = 0; tdma_rfTxInfo.pPayload[TDMA_SLOT_SIZE] = tdma_slot_len_ms; nrk_time_get (&_tdma_next_wakeup); tdma_rfTxInfo.destAddr = 0xffff; tdma_rfTxInfo.ackRequest = 0; tdma_rfTxInfo.cca = 0; _tdma_tx (); rf_rx_on (); } else { // Upstream data slot v = _tdma_rx (); if (v == 1) tdma_last_tx_slot = slot; } slot++; if (slot >= tdma_slots_per_cycle + 1) slot = 0; nrk_time_add (&_tdma_next_wakeup, _tdma_next_wakeup, _tdma_slot_time); nrk_time_compact_nanos (&_tdma_next_wakeup); nrk_wait_until (_tdma_next_wakeup); }
void uart_task() { char c; nrk_sig_t uart_rx_signal; //nrk_sig_mask_t sm; uint8_t buf_pos = 0; uint8_t vbuf_pos = 0; uint8_t pos = 0; uint8_t other_active = 1; uint8_t version_buf[VERSION_BUF_SIZE]; int16_t my_version = 0; uint8_t connection_l; uint8_t activate_uart_l; uint8_t ack_received_l; if(log_g) printf("log:uart_task PID=%d\r\n",nrk_get_pid()); // Get the signal for UART RX uart_rx_signal=nrk_uart_rx_signal_get(); // Register your task to wakeup on RX Data if(uart_rx_signal==NRK_ERROR) nrk_kprintf( PSTR("log:Get Signal ERROR!\r\n") ); nrk_signal_register(uart_rx_signal); while(1) { nrk_sem_pend(conn_sem); connection_l = connection_g; nrk_sem_post(conn_sem); nrk_sem_pend(ack_sem); ack_received_l = ack_received_g; nrk_sem_post(ack_sem); if(activate_uart_g == 1 && other_active == 1) { memset(uart_rx_buf,0,buf_pos); buf_pos = 0; if(log_g) printf("log:Switching off logs\r\n"); req_for_next_data(); log_g = 0; other_active = 0; } else if(activate_uart_g == 0 && vertsk_active_g == 0) { nrk_wait_until_next_period(); continue; } else if(activate_uart_g == 0 && connection_l == 0 && vertsk_active_g == 1) { // assuming this completes in one period if(log_g)nrk_kprintf(PSTR("verreq\n")); log_g = 0; while(nrk_uart_data_ready(NRK_DEFAULT_UART)!=0) { // Read Character c=getchar(); if(vbuf_pos >= VERSION_BUF_SIZE) { vbuf_pos = 0; nrk_kprintf(PSTR("Ver buf ovflw\n")); } version_buf[vbuf_pos++] = c; nrk_led_toggle(GREEN_LED); if(c =='&') { log_g = 1; version_buf[vbuf_pos++] = '\0'; pos = 0; my_version = get_next_int(version_buf,&pos,vbuf_pos); if(log_g) printf("log:Ver %d\n",my_version); version_g[MAC_ADDR] = my_version; if(vbuf_pos > 6) { if(log_g)nrk_kprintf(PSTR("Cnct Frnd\n")); pos++; bmac_tx_pkt(version_buf+pos,vbuf_pos-pos); } vertsk_active_g = 0; vbuf_pos = 0; } else if (c == '$') { vbuf_pos = 0; } } log_g = 1; nrk_wait_until_next_period(); continue; } nrk_sem_pend(conn_sem); connection_l = connection_g; nrk_sem_post(conn_sem); nrk_sem_pend(ack_sem); ack_received_l = ack_received_g; nrk_sem_post(ack_sem); if(ack_received_l == 1 && connection_l == 1) { while(nrk_uart_data_ready(NRK_DEFAULT_UART)!=0) { // Read Character c=getchar(); uart_rx_buf[buf_pos++] = c; nrk_led_toggle(GREEN_LED); if(c =='$') { log_g = 1; uart_rx_buf[buf_pos++] = '\0'; if(log_g) nrk_kprintf(PSTR("log:From UART\n")); if(log_g) printf("log:%s\n",uart_rx_buf); activate_uart_g = 0; other_active = 1; // tx a packet bmac_tx_pkt(uart_rx_buf,buf_pos); nrk_sem_pend(ack_sem); ack_received_g = 0; nrk_sem_post(ack_sem); ack_received_l = 0; pending_retransmit_g = 1; } else if (c == '&') { buf_pos = 0; } } log_g = 1; } //sm=nrk_event_wait(SIG(uart_rx_signal)); //if(sm != SIG(uart_rx_signal)) // nrk_kprintf( PSTR("RX signal error\n") ); nrk_wait_until_next_period(); } }
int8_t slip_rx (uint8_t * buf, uint8_t max_len) { uint8_t c; uint8_t index, last_c; uint8_t received, checksum, size; int8_t v; my_uart_rx_signal=nrk_uart_rx_signal_get(); // Register your task to wakeup on RX Data if (my_uart_rx_signal == NRK_ERROR) nrk_kprintf (PSTR ("SLIP RX error: Get Signal\r\n")); v=nrk_signal_register (my_uart_rx_signal); if(v==NRK_ERROR) nrk_kprintf( PSTR( "SLIP RX error: nrk_signal_register\r\n" )); received = 0; if( nrk_uart_data_ready (NRK_DEFAULT_UART) == 0) sm = nrk_event_wait (SIG (my_uart_rx_signal)); // Wait until you receive the packet start (START) command while (1) { // Wait for UART signal while (nrk_uart_data_ready (NRK_DEFAULT_UART) != 0) { // Read Character //c = getchar (); c = get_byte(); if (c == START) goto start; } if( nrk_uart_data_ready (NRK_DEFAULT_UART) == 0) sm = nrk_event_wait (SIG (my_uart_rx_signal)); c = get_byte(); //c = getchar (); if (c == START) break; } start: size = get_byte (); checksum = 0; while (1) { if( nrk_uart_data_ready (NRK_DEFAULT_UART) == 0) sm = nrk_event_wait (SIG (my_uart_rx_signal)); while (nrk_uart_data_ready (NRK_DEFAULT_UART) != 0) { last_c = c; //c = getchar (); c = get_byte(); // handle bytestuffing if necessary switch (c) { // if it's an END character then we're done with // the packet case END: // a minor optimization: if there is no // data in the packet, ignore it. This is // meant to avoid bothering IP with all // the empty packets generated by the // duplicate END characters which are in // turn sent to try to detect line noise. if (received) { checksum &= 0x7f; if (last_c == checksum) return received; } nrk_kprintf( PSTR( "Checksum failed: ") ); printf( "%d %d %d\r\n",received, last_c, checksum ); //return NRK_ERROR; return received; break; // if it's the same code as an ESC character, wait // and get another character and then figure out // what to store in the packet based on that. case ESC: last_c = c; if( nrk_uart_data_ready (NRK_DEFAULT_UART)==0 ) sm = nrk_event_wait (SIG (my_uart_rx_signal)); c = get_byte (); // if "c" is not one of these two, then we // have a protocol violation. The best bet // seems to be to leave the byte alone and // just stuff it into the packet switch (c) { case END: c = END; break; case ESC: c = ESC; break; } // here we fall into the default handler and let // it store the character for us default: if (received < max_len && received < size) { buf[received++] = c; checksum += c; } } } } return 0; }
nrk_sig_t tdma_get_tx_done_signal () { nrk_signal_register (tdma_tx_pkt_done_signal); return (tdma_tx_pkt_done_signal); }
void tx_task () { // Get the signal for UART RX //uart_rx_signal=nrk_uart_rx_signal_get(); // Register your task to wakeup on RX Data //if(uart_rx_signal==NRK_ERROR) nrk_kprintf( PSTR("Get Signal ERROR!\r\n") ); //nrk_signal_register(uart_rx_signal); //printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... bmac_init (26); bmac_encryption_set_key(aes_key,16); bmac_encryption_enable(); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); //nrk_kprintf (PSTR ("bmac_started()\r\n")); bmac_set_cca_thresh (-45); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); rx_signal = bmac_get_rx_pkt_signal (); nrk_signal_register (rx_signal); cnt = 0; while (1) { nrk_kprintf(PSTR("\r\n*************************************************************\r\n")); nrk_kprintf(PSTR(" PHOENIX WIRELESS UPDATE SYSTEM \r\n")); nrk_kprintf(PSTR("*************************************************************\r\n")); nrk_kprintf(PSTR("Press 'p' : To PING Nodes in Vicinity \r\n")); nrk_kprintf(PSTR("Press 'u' : To Begin Node Update \r\n")); nrk_kprintf(PSTR(" \r\n")); nrk_kprintf(PSTR("*************************************************************\r\n")); printf("Enter Choice: "); //sm=nrk_event_wait(SIG(uart_rx_signal)); //if(sm != SIG(uart_rx_signal)) //{ // nrk_kprintf( PSTR("UART signal error\r\n") ); // while(1); //} // Wait for UART signal while(1) { if(nrk_uart_data_ready(NRK_DEFAULT_UART)!=0) { // Read Character c=getchar(); printf( "%c\r\n",c); break; } timeout.secs = 0; timeout.nano_secs = 20 * NANOS_PER_MS; nrk_wait(timeout); } // Choose mode switch(c){ case 'p': programState = PING; break; case 'u': getDestMac(); phoenix_init(); programState = UPDATE; break; default: programState = NONE; nrk_kprintf(PSTR("Invalid Command! Please Try Again\r\n")); } // Reset c c = 0; nrk_wait_until_next_period(); // Execute protocol switch(programState) { case PING: pingMode(); break; case UPDATE: updateMode(); break; case NONE:;// Do nothing break; default: nrk_kprintf(PSTR("Invalid Program State\r\n")); break; } nrk_wait_until_next_period (); } }
void tx_task () { uint8_t j, i, val, len, cnt; int8_t v; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; nrk_time_t r_period; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... while (!bmac_started ()) nrk_wait_until_next_period (); // Sample of using Reservations on TX packets // This example allows 2 packets to be sent every 5 seconds // r_period.secs=5; // r_period.nano_secs=0; // v=bmac_tx_reserve_set( &r_period, 2 ); // if(v==NRK_ERROR) nrk_kprintf( PSTR("Error setting b-mac tx reservation (is NRK_MAX_RESERVES defined?)\r\n" )); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); ctr_cnt[0]=0; ctr_cnt[1]=0; ctr_cnt[2]=0; ctr_cnt[3]=0; cnt = 0; nrk_led_set(3); while (1) { // Build a TX packet sprintf (tx_buf, "This is a test %d", cnt); //nrk_led_set (BLUE_LED); // Auto ACK is an energy efficient link layer ACK on packets // If Auto ACK is enabled, then bmac_tx_pkt() will return failure // if no ACK was received. In a broadcast domain, the ACK's will // typically collide. To avoid this, one can use address decoding. // The functions are as follows: // bmac_auto_ack_enable(); // bmac_auto_ack_disable(); // Address decoding is a way of preventing the radio from receiving // packets that are not address to a particular node. This will // supress ACK packets from nodes that should not automatically ACK. // The functions are as follows: // bmac_addr_decode_set_my_mac(uint16_t MAC_ADDR); // bmac_addr_decode_dest_mac(uint16_t DST_ADDR); // 0xFFFF is broadcast // bmac_addr_decode_enable(); // bmac_addr_decode_disable(); ctr_cnt[0]=cnt; if(ctr_cnt[0]==255) ctr_cnt[1]++; if(ctr_cnt[1]==255) ctr_cnt[2]++; if(ctr_cnt[2]==255) ctr_cnt[3]++; // You need to increase the ctr on each packet to make the // stream cipher not repeat. bmac_encryption_set_ctr_counter(&ctr_cnt,4); // Disable CCA // bmac_set_cca_active(0); // For blocking transmits, use the following function call. // For this there is no need to register val=bmac_tx_pkt(tx_buf, strlen(tx_buf)); if(val==NRK_OK) cnt++; else nrk_kprintf( PSTR( "NO ack or Reserve Violated!\r\n" )); // This function shows how to transmit packets in a // non-blocking manner // val = bmac_tx_pkt_nonblocking(tx_buf, strlen (tx_buf)); // nrk_kprintf (PSTR ("Tx packet enqueued\r\n")); // This functions waits on the tx_done_signal // ret = nrk_event_wait (SIG(tx_done_signal)); // Just check to be sure signal is okay // if(ret & SIG(tx_done_signal) == 0 ) // nrk_kprintf (PSTR ("TX done signal error\r\n")); // If you want to see your remaining reservation // printf( "reserve=%d ",bmac_tx_reserve_get() ); // Task gets control again after TX complete nrk_kprintf (PSTR ("Tx task sent data!\r\n")); //nrk_led_clr (BLUE_LED); nrk_wait_until_next_period (); } }
void bmac_nw_task () { int8_t v, i; 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 rf_power_up (); if (is_enabled) { v = 1; #ifdef BMAC_MOD_CCA if (rx_buf_empty == 1) { if (_bmac_rx () == 1) e = nrk_event_signal (bmac_rx_pkt_signal); } else e = nrk_event_signal (bmac_rx_pkt_signal); #else 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" )); } #endif if (tx_data_ready == 1) { _bmac_tx (); } rf_rx_off (); rf_power_down (); //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 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 tx_task () { uint8_t j, i, cnt, error; int8_t len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_sig_t tx_done_signal; nrk_sig_t rx_signal; nrk_sig_mask_t ret; nrk_time_t check_period; nrk_time_t timeout, start, current; nrk_sig_mask_t my_sigs; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... bmac_init (26); // Configure address for other packet handlers (my not be needed) my_mac= MY_MAC; my_subnet_mac[0]= MY_SUBNET_MAC_0; my_subnet_mac[1]= MY_SUBNET_MAC_1; my_subnet_mac[2]= MY_SUBNET_MAC_2; mac_address= (uint8_t)MY_SUBNET_MAC_2 << 24 | (uint8_t)MY_SUBNET_MAC_1 <<16 | (uint8_t)MY_SUBNET_MAC_0 << 8 | (uint8_t)MY_MAC; while (!bmac_started ()) nrk_wait_until_next_period (); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); val = bmac_addr_decode_set_my_mac (((uint16_t) MY_SUBNET_MAC_0 << 8) | MY_MAC); val = bmac_addr_decode_dest_mac (0xffff); // broadcast by default bmac_addr_decode_enable (); nrk_kprintf (PSTR ("bmac_started()\r\n")); bmac_set_cca_thresh (-45); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); rx_signal = bmac_get_rx_pkt_signal (); nrk_signal_register (rx_signal); cnt = 0; while (1) { // Build a TX packet by hand... p2p_pkt.pkt_type = DATA_STORAGE_PKT; p2p_pkt.ctrl_flags = LINK_ACK | MOBILE_MASK; // | DEBUG_FLAG ; p2p_pkt.ack_retry = 0x0f; p2p_pkt.ttl = 1; p2p_pkt.src_subnet_mac[0] = MY_SUBNET_MAC_0; p2p_pkt.src_subnet_mac[1] = MY_SUBNET_MAC_1; p2p_pkt.src_subnet_mac[2] = MY_SUBNET_MAC_2; p2p_pkt.src_mac = MY_MAC; p2p_pkt.last_hop_mac = MY_MAC; // p2p_pkt.dst_subnet_mac[0] = BROADCAST; // p2p_pkt.dst_subnet_mac[1] = BROADCAST; // p2p_pkt.dst_subnet_mac[2] = BROADCAST; // p2p_pkt.dst_mac = BROADCAST; p2p_pkt.dst_subnet_mac[0] = BROADCAST; p2p_pkt.dst_subnet_mac[1] = BROADCAST; p2p_pkt.dst_subnet_mac[2] = BROADCAST; p2p_pkt.dst_mac = 0x1; p2p_pkt.buf = tx_buf; p2p_pkt.buf_len = P2P_PAYLOAD_START; p2p_pkt.seq_num = cnt; p2p_pkt.priority = 0; p2p_pkt.check_rate = 100; p2p_pkt.payload = &(tx_buf[P2P_PAYLOAD_START]); cnt++; #ifdef TEST_WRITE data_pkt.mode=EE_WRITE; data_pkt.addr=0x110; // Must be greater than 0x100 data_pkt.data_len=0x10; // point the eeprom data structure to our local data buffer data_pkt.eeprom_payload=eeprom_data; // copy over some data for(i=0; i<data_pkt.data_len; i++ ) data_pkt.eeprom_payload[i]=i; #endif #ifdef TEST_READ data_pkt.mode=EE_READ; data_pkt.addr=0x200; // Must be greater than 0x100 data_pkt.data_len=0x3d; #endif // add the eeprom pkt to the p2p pkt p2p_pkt.payload_len= eeprom_storage_pkt_pack(&data_pkt, p2p_pkt.payload); // Pack data structure values in buffer before transmit pack_peer_2_peer_packet (&p2p_pkt); nrk_led_set (BLUE_LED); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); nrk_kprintf( PSTR("sending: " )); for(i=0; i<p2p_pkt.buf_len; i++ ) printf( "%u ",p2p_pkt.buf[i] ); printf( "\r\n" ); // For blocking transmits, use the following function call. val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); check_period.secs = 0; check_period.nano_secs = FAST_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("\r\nSent Request:\r\n")); #endif nrk_led_clr (BLUE_LED); nrk_led_clr (GREEN_LED); // Wait for packets or timeout nrk_time_get (&start); while (1) { timeout.secs = REPLY_WAIT_SECS; timeout.nano_secs = 0; // Wait until an RX packet is received //val = bmac_wait_until_rx_pkt (); if(bmac_rx_pkt_ready()==0) { nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); } if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) { // Set the buffer p2p_pkt.buf = local_rx_buf; p2p_pkt.buf_len = len; p2p_pkt.rssi = rssi; unpack_peer_2_peer_packet (&p2p_pkt); #ifdef TXT_DEBUG if ((p2p_pkt.dst_subnet_mac[2] == MY_SUBNET_MAC_2 && p2p_pkt.dst_subnet_mac[1] == MY_SUBNET_MAC_1 && p2p_pkt.dst_subnet_mac[0] == MY_SUBNET_MAC_0 && p2p_pkt.dst_mac == MY_MAC ) || p2p_pkt.dst_mac == BROADCAST) { nrk_led_set (GREEN_LED); // Packet arrived and is good to go printf ("full mac: %d %d %d %d ", p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2], p2p_pkt.src_mac); printf ("rssi: %d ", p2p_pkt.rssi); printf ("type: %d ", p2p_pkt.pkt_type); nrk_kprintf (PSTR ("payload: [")); for (i = 0; i < p2p_pkt.payload_len; i++) printf ("%d ", p2p_pkt.payload[i]); nrk_kprintf (PSTR ("]\r\n")); if(p2p_pkt.pkt_type== DATA_STORAGE_PKT ) { eeprom_storage_pkt_unpack(&data_pkt, p2p_pkt.payload ); nrk_kprintf( PSTR("\r\n Storage Packet " )); nrk_kprintf( PSTR("\r\n Mode: " )); switch(data_pkt.mode) { case EE_REPLY: nrk_kprintf( PSTR( "Reply")); break; case EE_ERROR: nrk_kprintf( PSTR( "Error" )); break; case EE_READ: nrk_kprintf( PSTR( "Read" )); break; case EE_WRITE: nrk_kprintf( PSTR( "Write" )); break; default: nrk_kprintf( PSTR( "unknown" )); } nrk_kprintf( PSTR("\r\n From: " )); printf( "%u",data_pkt.mac ); nrk_kprintf( PSTR("\r\n Addr: " )); printf( "%u",data_pkt.addr); nrk_kprintf( PSTR("\r\n Len: " )); printf( "%u",data_pkt.data_len); nrk_kprintf( PSTR("\r\n Data: " )); for(i=0; i<data_pkt.data_len; i++ ) printf( "%u ",data_pkt.eeprom_payload[i]); nrk_kprintf( PSTR("\r\n" )); } } #endif } } nrk_time_get (¤t); if (start.secs + REPLY_WAIT_SECS < current.secs) break; // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } nrk_kprintf (PSTR ("Done Waiting for response...\r\n")); nrk_wait_until_next_period (); } }
void tx_task () { uint8_t j, i, error,unique; uint8_t samples; int8_t len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_sig_t tx_done_signal; nrk_sig_t rx_signal; nrk_sig_mask_t ret; nrk_time_t check_period; nrk_time_t timeout, start, current; nrk_sig_mask_t my_sigs; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... bmac_init (26); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); val=bmac_addr_decode_set_my_mac(((uint16_t)MY_SUBNET_MAC_0<<8)|MY_MAC); val=bmac_addr_decode_dest_mac(0xffff); // broadcast by default bmac_addr_decode_enable(); nrk_kprintf (PSTR ("bmac_started()\r\n")); bmac_set_cca_thresh (-45); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); rx_signal = bmac_get_rx_pkt_signal (); nrk_signal_register (rx_signal); cnt = 0; check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); while (1) { my_nlist_elements=0; for(samples=0; samples<10; samples++ ) { nrk_led_set (GREEN_LED); check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); build_ping_pkt( &p2p_pkt ); // Pack data structure values in buffer before transmit pack_peer_2_peer_packet(&p2p_pkt); // For blocking transmits, use the following function call. val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); check_period.secs = 0; check_period.nano_secs = p2p_pkt.check_rate * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("\r\nSent Request:\r\n")); #endif nrk_led_clr (GREEN_LED); // Wait for packets or timeout nrk_time_get (&start); while (1) { timeout.secs = REPLY_WAIT_SECS; timeout.nano_secs = 0; // Wait until an RX packet is received //val = bmac_wait_until_rx_pkt (); nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) { // Set the buffer p2p_pkt.buf=local_rx_buf; p2p_pkt.buf_len=len; p2p_pkt.rssi=rssi; unpack_peer_2_peer_packet(&p2p_pkt); #ifdef TXT_DEBUG // Check if newly received packet is for this node if (((p2p_pkt.dst_subnet_mac[2] == MY_SUBNET_MAC_2 && p2p_pkt.dst_subnet_mac[1] == MY_SUBNET_MAC_1 && p2p_pkt.dst_subnet_mac[0] == MY_SUBNET_MAC_0 && p2p_pkt.dst_mac == MY_MAC ) || p2p_pkt.dst_mac == BROADCAST) && p2p_pkt.pkt_type==PING_PKT) { // Packet arrived and is good to go printf( "src: %d ",p2p_pkt.src_mac); printf( "rssi: %d ",p2p_pkt.rssi); printf( "subnet: %d %d %d ",p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2]); printf( "type: %d ",p2p_pkt.pkt_type); nrk_kprintf (PSTR ("payload: [")); for (i = 0; i < p2p_pkt.payload_len; i++) printf ("%d ", p2p_pkt.payload[i]); nrk_kprintf (PSTR ("]\r\n")); unique=1; // Check if the MAC is unique for(i=0; i<my_nlist_elements; i++ ) { if(my_nlist[i*NLIST_SIZE]==p2p_pkt.src_subnet_mac[2] && my_nlist[i*NLIST_SIZE+1]==p2p_pkt.src_subnet_mac[1] && my_nlist[i*NLIST_SIZE+2]==p2p_pkt.src_subnet_mac[0] && my_nlist[i*NLIST_SIZE+3]==p2p_pkt.src_mac) { unique=0; break; } } // If MAC is unique, add it if(unique) { my_nlist[my_nlist_elements*NLIST_SIZE]=p2p_pkt.src_subnet_mac[2]; my_nlist[my_nlist_elements*NLIST_SIZE+1]=p2p_pkt.src_subnet_mac[1]; my_nlist[my_nlist_elements*NLIST_SIZE+2]=p2p_pkt.src_subnet_mac[0]; my_nlist[my_nlist_elements*NLIST_SIZE+3]=p2p_pkt.src_mac; my_nlist[my_nlist_elements*NLIST_SIZE+4]=p2p_pkt.rssi; my_nlist_elements++; } } #endif } // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } nrk_time_get (¤t); if (start.secs + REPLY_WAIT_SECS < current.secs) break; } cnt++; } check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); nrk_kprintf (PSTR ("Done Waiting for response...\r\n")); nrk_kprintf (PSTR ("\r\n\r\nSurvey Says:\r\n")); nrk_kprintf( PSTR("LOC_DESC: \"location name\"\r\n" )); for(i=0; i<my_nlist_elements; i++ ) { nrk_kprintf( PSTR( "MAC: " )); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE] ); else printf( "%x", my_nlist[i*NLIST_SIZE] ); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE+1] ); else printf( "%x", my_nlist[i*NLIST_SIZE+1] ); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE+2] ); else printf( "%x", my_nlist[i*NLIST_SIZE+2] ); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE+3] ); else printf( "%x", my_nlist[i*NLIST_SIZE+3] ); printf( " RSSI: %d\r\n", (int8_t)my_nlist[i*NLIST_SIZE+4] ); } nrk_wait_until_next_period (); } }
void tx_task () { uint8_t i, unique; uint8_t samples ; uint8_t len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_sig_t tx_done_signal; nrk_sig_t rx_signal; nrk_time_t check_period; nrk_time_t timeout, start, current; nrk_sig_mask_t my_sigs; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... bmac_init (26); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); val = bmac_addr_decode_set_my_mac (((uint16_t) MY_SUBNET_MAC_0 << 8) | MY_MAC ); val = bmac_addr_decode_dest_mac (0xffff); // broadcast by default bmac_addr_decode_enable (); nrk_kprintf (PSTR ("bmac_started()\r\n")); bmac_set_cca_thresh (-45); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); rx_signal = bmac_get_rx_pkt_signal (); nrk_signal_register (rx_signal); cnt = 0; check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Main loop that does: // 1) Sends out ping message // 2) Collects replies, build neighbor list and then times out // 3) Repeat 1 and 2 for 3 times // 4) Build Extended Neighborlist packet // 5) Send Neighbor list packet // 6) Wait until next period and repeat 1-6 while (1) { nrk_led_clr (ORANGE_LED); // Set our local neighbor list to be empty my_nlist_elements = 0; for (samples = 0; samples < 3; samples++) { nrk_led_set (GREEN_LED); check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Construct a ping packet to send (this is being built into tx_buf) build_ping_pkt (&p2p_pkt); // Pack data structure values in buffer before transmit pack_peer_2_peer_packet (&p2p_pkt); // Send the Ping packet val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); // Set update rate based on p2p reply rate. // This is usually faster to limit congestion check_period.secs = 0; check_period.nano_secs = p2p_pkt.check_rate * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("Pinging...\r\n")); #endif nrk_led_clr (GREEN_LED); // Grab start time for timeout nrk_time_get (&start); while (1) { // Set the amount of time to wait for timeout timeout.secs = REPLY_WAIT_SECS; timeout.nano_secs = 0; // Check if packet is already ready, or wait until one arrives // Also set timeout to break from function if no packets come my_sigs=0; if (bmac_rx_pkt_ready () == 0) { nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); } if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) { // Setup a p2p packet data structure with the newly received buffer p2p_pkt.buf = local_rx_buf; p2p_pkt.buf_len = len; p2p_pkt.rssi = rssi; // Unpack the data from the array into the p2p_pkt data struct unpack_peer_2_peer_packet (&p2p_pkt); // Check if newly received packet is for this node if (((p2p_pkt.dst_subnet_mac[2] == MY_SUBNET_MAC_2 && p2p_pkt.dst_subnet_mac[1] == MY_SUBNET_MAC_1 && p2p_pkt.dst_subnet_mac[0] == MY_SUBNET_MAC_0 && p2p_pkt.dst_mac == MY_MAC ) || p2p_pkt.dst_mac == BROADCAST) && (p2p_pkt.pkt_type == PING_PKT)) { // Packet arrived and is ping pkt! // Lets print some values out on the terminal printf ("full mac: %d %d %d %d ", p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2], p2p_pkt.src_mac); printf ("rssi: %d ", p2p_pkt.rssi); printf ("type: %d ", p2p_pkt.pkt_type); nrk_kprintf (PSTR ("payload: [")); for (i = 0; i < p2p_pkt.payload_len; i++) printf ("%d ", p2p_pkt.payload[i]); nrk_kprintf (PSTR ("]\r\n")); unique = 1; // Check if the MAC of this ping is unique or if it already // exists in our neighbor list for (i = 0; i < my_nlist_elements; i++) { if (my_nlist[i * NLIST_SIZE] == p2p_pkt.src_subnet_mac[2] && my_nlist[i * NLIST_SIZE + 1] == p2p_pkt.src_subnet_mac[1] && my_nlist[i * NLIST_SIZE + 2] == p2p_pkt.src_subnet_mac[0] && my_nlist[i * NLIST_SIZE + 3] == p2p_pkt.src_mac) { unique = 0; break; } } // If MAC is unique, add it to our neighbor list if (unique) { my_nlist[my_nlist_elements * NLIST_SIZE] = p2p_pkt.src_subnet_mac[2]; my_nlist[my_nlist_elements * NLIST_SIZE + 1] = p2p_pkt.src_subnet_mac[1]; my_nlist[my_nlist_elements * NLIST_SIZE + 2] = p2p_pkt.src_subnet_mac[0]; my_nlist[my_nlist_elements * NLIST_SIZE + 3] = p2p_pkt.src_mac; my_nlist[my_nlist_elements * NLIST_SIZE + 4] = p2p_pkt.rssi; my_nlist_elements++; } } } } // Check if we are done waiting for pings nrk_time_get (¤t); if (start.secs + REPLY_WAIT_SECS < current.secs) break; // exit loops waiting for pings // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); // Go back to top loop to wait for more pings } cnt++; // Repeat ping 3 times } // Now we are ready to build extended neighborlist packet and send it to gateway check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); nrk_kprintf (PSTR ("Done Waiting for response...\r\n")); // If we have any neighbors, build the list if (my_nlist_elements > 0) { // Look in this function for format of extended neighborlist packet // This function also configures the parameters and destination address // of the p2p packet. The values are probably okay as defaults. build_extended_neighbor_list_pkt (&p2p_pkt, my_nlist, my_nlist_elements); // This function takes at p2p struct and packs it into an array for sending pack_peer_2_peer_packet (&p2p_pkt); nrk_led_set (BLUE_LED); // Send the list to the gateway. val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); printf ("size of pkt: %d\r\n", p2p_pkt.buf_len); nrk_kprintf (PSTR ("sent neighbor list packet\r\n")); nrk_led_clr (BLUE_LED); } else { nrk_led_set (RED_LED); nrk_spin_wait_us (1000); nrk_led_clr (RED_LED); } // Wait a long time until we send out the pings again // This is in a loop so that period can be small for // other uses. for (i = 0; i < 10; i++) nrk_wait_until_next_period (); // Might as well release packets that arrived during long // break since they are not replies to your ping. bmac_rx_pkt_release (); } }
/* void inter_tx_task () { uint8_t j, i, val, len, cnt; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; nrk_time_t r_period; while (!bmac_started ()) nrk_wait_until_next_period (); tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); cnt = 0; while (1) { if(inter_flag==1){ printf("Hi..\n"); bmac_addr_decode_disable(); bmac_addr_decode_set_my_mac(MY_MAC_ADDR); sprintf(&tx_buf[0],"%d",MY_MAC_ADDR); for(i=0;i<strlen(inter_tx_buf);i++){ tx_buf[i+1]=inter_tx_buf[i]; } nrk_led_set (BLUE_LED); bmac_auto_ack_disable(); bmac_addr_decode_dest_mac(dst_addr); // 0xFFFF is broadcast val=bmac_tx_pkt(tx_buf, strlen(tx_buf)); inter_flag=0; printf("Tx task sent data!\r\n"); nrk_led_clr (BLUE_LED); printf("tx_task PID=%d\r\n", nrk_get_pid ()); } nrk_wait_until_next_period (); } } */ void tx_task () { uint8_t j, i, val, len, cnt,turn=0; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; nrk_time_t r_period; while (!bmac_started ()) nrk_wait_until_next_period (); tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); cnt = 0; while (1) { if(inter_flag==0 ){ printf("Hi..\n"); bmac_addr_decode_disable(); bmac_addr_decode_set_my_mac(MY_MAC_ADDR); sprintf(tx_buf,"node_id:%d count:%d",MY_MAC_ADDR,cnt); nrk_led_set (BLUE_LED); bmac_auto_ack_disable(); bmac_addr_decode_dest_mac(dst_addr); // 0xFFFF is broadcast val=bmac_tx_pkt(tx_buf, strlen(tx_buf)); printf("Tx task sent data!\r\n"); nrk_led_clr (BLUE_LED); printf("tx_task PID=%d\r\n", nrk_get_pid ()); } if(inter_flag==1){ if(turn==0){ printf("Hi..\n"); bmac_addr_decode_disable(); bmac_addr_decode_set_my_mac(MY_MAC_ADDR); sprintf(tx_buf,"Path: %d-1 node_id:%d count:%d",MY_MAC_ADDR,MY_MAC_ADDR,cnt); nrk_led_set (BLUE_LED); bmac_auto_ack_disable(); bmac_addr_decode_dest_mac(dst_addr); // 0xFFFF is broadcast val=bmac_tx_pkt(tx_buf, strlen(tx_buf)); printf("Tx task sent data!\r\n"); nrk_led_clr (BLUE_LED); printf("tx_task PID=%d\r\n", nrk_get_pid ()); turn=1; } else{ bmac_addr_decode_disable(); bmac_addr_decode_set_my_mac(MY_MAC_ADDR); sprintf(&tx_buf[0],"%d",MY_MAC_ADDR); for(i=0;i<strlen(inter_tx_buf);i++){ tx_buf[i+1]=inter_tx_buf[i]; } nrk_led_set (BLUE_LED); bmac_auto_ack_disable(); bmac_addr_decode_dest_mac(dst_addr); // 0xFFFF is broadcast val=bmac_tx_pkt(tx_buf, strlen(tx_buf)); printf("Tx task sent data!\r\n"); nrk_led_clr (BLUE_LED); printf("tx_task PID=%d\r\n", nrk_get_pid ()); turn=0; } } cnt++; nrk_wait_until_next_period (); } }
void Task5() { int8_t v; nrk_sig_mask_t my_sigs; nrk_sig_t t; nrk_time_t timeout; // timeout.secs=10; // timeout.nano_secs=0; printf( "Task5 PID=%d\r\n",nrk_get_pid()); v=nrk_signal_register(signal_one); // v=nrk_signal_register(nrk_wakeup_signal); // if(v==NRK_ERROR) // nrk_kprintf( PSTR ("T2 nrk_signal_register failed\r\n")); while(1) { // nrk_led_toggle(BLUE_LED); // nrk_set_next_wakeup(timeout); // printf("ee"); // my_sigs=nrk_event_wait(SIG(signal_one) | SIG(nrk_wakeup_signal)); F_ReadyForSignal_U8R=1; my_sigs=nrk_event_wait(SIG(signal_one)); nrk_led_set(RED_LED); F_ReadyForSignal_U8R=0; if(my_sigs==0) nrk_kprintf( PSTR ("T2 nrk_event_wait failed\r\n")); if(my_sigs & SIG(signal_one)) { // nrk_kprintf( PSTR( "T2 got S1\r\n")); // nrk_kprintf( PSTR("*")); slip_tx(&V_TxBuff_U8R[V_RdPtr_U32R],C_SlipPktSize,&V_TxBuff_U8R[C_CircBuffSize-1],C_CircBuffSize); // printf("\r\n%d",V_WrPtr_U32R); // printf(",%d",V_RdPtr_U32R); V_RdPtr_U32R=V_RdPtr_U32R+C_SlipPktSize; if(V_RdPtr_U32R>=C_CircBuffSize) { V_RdPtr_U32R = V_RdPtr_U32R - C_CircBuffSize; V_WrSeqNo_U8R = 0; } if(F_Det_U8R==1) { printf("\r\nEvent!"); F_Det_U8R = 0; } if(F_1secData_U8R==1) { F_1secData_U8R = 0; V_CalcTemp1_U32R = V_ArmsVolt_U32R*33; V_CalcTemp2_U32R = V_CalcTemp1_U32R/1000000; // printf("\r\nV = %ld",V_ArmsVolt_U32R); printf("\r\n%ld V",V_CalcTemp2_U32R); V_CalcTemp1_U32R = V_ArmsCurr_U32R*125; V_CalcTemp2_U32R = V_CalcTemp1_U32R/10000; printf(", %ld mA",V_CalcTemp2_U32R); // printf(", I = %ld",V_ArmsCurr_U32R); V_CalcTemp1_S32R = V_ArmsWatt_S32R; V_CalcTemp2_S32R = V_CalcTemp1_S32R/10; V_CalcTemp1_S32R = V_CalcTemp2_S32R*344; V_CalcTemp2_S32R = V_CalcTemp1_S32R/100000; // V_AwattCalc1_U32R = V_Awatt_S32R*3; // V_AwattCalc2_U32R = (V_AwattCalc1_U32R>>13); // printf(" P = %ld",V_AwattCalc2_U32R);i printf(", P = %ld W",V_CalcTemp2_S32R); V_RdDSP_U16R = ade_read16(RUN); if(V_RdDSP_U16R==0) { ade_write16(RUN,START); // printf("\nDSP restarted"); printf("\r\r$$"); } } nrk_led_clr(RED_LED); } // if(my_sigs & SIG(nrk_wakeup_signal)) // nrk_kprintf( PSTR( "T2 timeout\r\n")); // nrk_wait_until_next_period(); } }
void gateway_task () { uint8_t i, len; int8_t rssi, val; uint8_t *local_rx_tx_buf; uint16_t batt; nrk_time_t check_period, wait_time; uint16_t buf; int8_t fd; uint8_t j, cnt, level; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; nrk_time_t next_transmit_time; nrk_time_t current_time; nrk_time_t prev_time; char tmp[4]; printf ("gateway_task PID=%d\r\n", nrk_get_pid ()); next_transmit_time.secs = 0; next_transmit_time.nano_secs = 0; // init bmac on channel 25 bmac_init (26); // By default the RX check rate is 100ms // below shows how to change that check_period.secs=0; check_period.nano_secs=100*NANOS_PER_MS; val=bmac_set_rx_check_rate(check_period); // The default Clear Channel Assement RSSI threshold is -32 // Setting this value higher means that you will only trigger // receive with a very strong signal. Setting this lower means // bmac will try to receive fainter packets. If the value is set // too high or too low performance will suffer greatly. // bmac_set_cca_thresh(-36); if(val==NRK_ERROR) nrk_kprintf( PSTR("ERROR setting bmac rate\r\n" )); // This sets the next RX buffer. // This can be called at anytime before releaseing the packet // if you wish to do a zero-copy buffer switch bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); nrk_time_set(0, 0); cnt = 0; // Initially clear all the data buffers for(i=0; i<(MAX_NODES);i++) { for(j=0; j<(WORDS_PER_NODE); j++) { data_pkt.node_specific_data[i][j] = 0; } } while (1) { nrk_time_get(¤t_time); // If it is time to flood the network, send the control packets if(current_time.secs%FLOOD_RATE == 0 && prev_time.secs != current_time.secs || cnt == 0) { prev_time = current_time; cnt ++; SET_PACKET_COUNT(pkt_buf.pkt_type_cnt, cnt); #if MODE==DATA_MODE SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_CONTROL); #else SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_DIAG_CONTROL); #endif pkt_buf.hop_number = 0; pkt_buf.time_to_flood = TIME_TO_FLOOD_IN_SECS; pkt_buf.bmac_check_rate = BMAC_CHECK_RATE_IN_MS; pkt_buf.maximum_depth = MAXIMUM_DEPTH; pkt_buf.delay_at_each_level = DELAY_AT_EACH_LEVEL_IN_SECS; pkt_buf.next_control_time = NEXT_CONTROL_TIME; pkt_buf.data_push_rate = 0; for(i=0; i<(MAX_NODES);i++) { for(j=0; j<(WORDS_PER_NODE); j++) { #if MODE==DATA_MODE pkt_buf.node_specific_data[i][j] = SENSOR; #else pkt_buf.node_specific_data[i][j] = 0; #endif } } memcpy(tx_buf, &pkt_buf, sizeof(pkt_buf)); // Non-blocking send nrk_led_set (BLUE_LED); val = bmac_tx_pkt_nonblocking (tx_buf, sizeof(struct message_packet)); nrk_kprintf (PSTR ("Tx packet enqueued\r\n")); ret = nrk_event_wait (SIG(tx_done_signal)); if(ret & SIG(tx_done_signal) == 0 ) nrk_kprintf (PSTR ("TX done signal error\r\n")); nrk_led_clr (BLUE_LED); } // If a new packet has been received, then update the information if(bmac_rx_pkt_ready()) { // Wait until an RX packet is received nrk_led_set (ORANGE_LED); // Get the RX packet local_rx_tx_buf = bmac_rx_pkt_get (&len, &rssi); for (i = 0; i < len; i++) printf ("%d", rx_buf[i]); printf ("\r\n"); memcpy(&pkt_buf, rx_buf, sizeof(pkt_buf)); nrk_led_clr (ORANGE_LED); // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); // If the received packet is a data packet then update the information, gateway just ignores the control packets if(GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DIAG_DATA || GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DATA) { printf("Type = %d\n\r", GET_PACKET_TYPE(pkt_buf.pkt_type_cnt)); printf("Count = %d\n\r", GET_PACKET_COUNT(pkt_buf.pkt_type_cnt)); printf("Hop # = %d\n\r", pkt_buf.hop_number); printf("TTF = %d\n\r", pkt_buf.time_to_flood); printf("BCR = %d\n\r", pkt_buf.bmac_check_rate); printf("Nmax = %d\n\r", pkt_buf.maximum_depth); printf("Dlev = %d\n\r", pkt_buf.delay_at_each_level); printf("Nxt = %d\n\r", pkt_buf.next_control_time); printf("Prate = %d\n\r", pkt_buf.data_push_rate); for(i=0; i<(MAX_NODES);i++) { for(j=0; j<(WORDS_PER_NODE); j++) { if(pkt_buf.node_specific_data[i][j] != 0) data_pkt.node_specific_data[i][j] = pkt_buf.node_specific_data[i][j]; } } for(i=0; i<(MAX_NODES);i++) { printf("Value @ Node %d is %d (cnt is %d)", i, ((int16_t)data_pkt.node_specific_data[i][1]<<4), (data_pkt.node_specific_data[i][0]&0x3F)); printf("\n\r"); } } } } }
nrk_sig_t tdma_get_rx_pkt_signal () { nrk_signal_register (tdma_rx_pkt_signal); return (tdma_rx_pkt_signal); }
void tx_task () { uint8_t j, i, val, len, byte_cnt, got_start; int8_t v; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; nrk_time_t r_period; nrk_sig_t uart_rx_signal; nrk_sig_mask_t sm; // Get the signal for UART RX uart_rx_signal=nrk_uart_rx_signal_get(); // Register your task to wakeup on RX Data if(uart_rx_signal==NRK_ERROR) nrk_kprintf( PSTR("Get Signal ERROR!\r\n") ); nrk_signal_register(uart_rx_signal); printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... while (!bmac_started ()) nrk_wait_until_next_period (); nrk_led_set(RED_LED); // Sample of using Reservations on TX packets // This example allows 2 packets to be sent every 5 seconds // r_period.secs=5; // r_period.nano_secs=0; // v=bmac_tx_reserve_set( &r_period, 2 ); // if(v==NRK_ERROR) nrk_kprintf( PSTR("Error setting b-mac tx reservation (is NRK_MAX_RESERVES defined?)\r\n" )); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); bmac_set_cca_active(0); ctr_cnt[0]=0; ctr_cnt[1]=0; ctr_cnt[2]=0; ctr_cnt[3]=0; while (1) { // Wait for UART signal got_start=0; byte_cnt=0; do { sm=nrk_event_wait(SIG(uart_rx_signal)); while(nrk_uart_data_ready(NRK_DEFAULT_UART)!=0) { // Read Character val=getchar(); tx_buf[byte_cnt]=val; if(got_start && val==0xff ) { nrk_led_toggle(ORANGE_LED); printf( "0xff byte: %d\n", byte_cnt ); byte_cnt=0; got_start=0; val=1; // Something other than 0xff so that the // got_start isn't set } if(val==0xff) { nrk_led_toggle(GREEN_LED); got_start=1; } if(got_start) byte_cnt++; if(byte_cnt>3) break; } } while(byte_cnt<4); // Build a TX packet nrk_led_set (BLUE_LED); // Auto ACK is an energy efficient link layer ACK on packets // If Auto ACK is enabled, then bmac_tx_pkt() will return failure // if no ACK was received. In a broadcast domain, the ACK's will // typically collide. To avoid this, one can use address decoding. // The functions are as follows: // bmac_auto_ack_enable(); // bmac_auto_ack_disable(); // Address decoding is a way of preventing the radio from receiving // packets that are not address to a particular node. This will // supress ACK packets from nodes that should not automatically ACK. // The functions are as follows: // bmac_addr_decode_set_my_mac(uint16_t MAC_ADDR); // bmac_addr_decode_dest_mac(uint16_t DST_ADDR); // 0xFFFF is broadcast // bmac_addr_decode_enable(); // bmac_addr_decode_disable(); ctr_cnt[0]++; if(ctr_cnt[0]==255) ctr_cnt[1]++; if(ctr_cnt[1]==255) ctr_cnt[2]++; if(ctr_cnt[2]==255) ctr_cnt[3]++; // You need to increase the ctr on each packet to make the // stream cipher not repeat. bmac_encryption_set_ctr_counter(&ctr_cnt,4); // For blocking transmits, use the following function call. // For this there is no need to register /* nrk_kprintf( PSTR("Sending: ") ); for(i=0; i<byte_cnt; i++ ) printf( "%d ",tx_buf[i] ); nrk_kprintf( PSTR("\r\n") ); */ val=bmac_tx_pkt(tx_buf, byte_cnt); // This function shows how to transmit packets in a // non-blocking manner // val = bmac_tx_pkt_nonblocking(tx_buf, strlen (tx_buf)); // nrk_kprintf (PSTR ("Tx packet enqueued\r\n")); // This functions waits on the tx_done_signal // ret = nrk_event_wait (SIG(tx_done_signal)); // Just check to be sure signal is okay // if(ret & SIG(tx_done_signal) == 0 ) // nrk_kprintf (PSTR ("TX done signal error\r\n")); // If you want to see your remaining reservation // printf( "reserve=%d ",bmac_tx_reserve_get() ); // Task gets control again after TX complete nrk_led_clr (BLUE_LED); } }
void event_detector_task() { update_energy_sig=nrk_signal_create(); if(update_energy_sig==NRK_ERROR) nrk_kprintf(PSTR("Error creating update_energy_sig signal!\r\n")); nrk_signal_register(update_energy_sig); if(v==NRK_ERROR) nrk_kprintf( PSTR( "nrk_signal_register failed\r\n" )); //ev_timeout.secs=10; //ev_timeout.nano_secs=0; while(1) { // Wait on signal //nrk_set_next_wakeup(ev_timeout); my_sigs=nrk_event_wait( SIG(update_energy_sig) /*| SIG(nrk_wakeup_signal)*/ ); if(my_sigs!=0 && ticks_last>900) { tmp_d=current_total_last / ticks_last; if(tmp_d<0) tmp_d=0; tmp_d=sqrt(tmp_d); rms_current=(uint16_t)tmp_d; tmp_d=current_total2_last / ticks_last; if(tmp_d<0) tmp_d=0; tmp_d=sqrt(tmp_d); rms_current2=(uint16_t)tmp_d; tmp_d=voltage_total_last / ticks_last; if(tmp_d<0) tmp_d=0; tmp_d=sqrt(tmp_d); rms_voltage=(uint16_t)tmp_d; if(energy_total_last<0) energy_total_last=0; true_power=energy_total_last / ticks_last; if(true_power>TRUE_POWER_ON_THRESH) cummulative_energy.total+=true_power; if(energy_total2_last<0) energy_total2_last=0; true_power2=energy_total2_last / ticks_last; if(true_power2>TRUE_POWER_ON_THRESH) cummulative_energy2.total+=true_power2; total_secs++; // Divide by seconds per hour to give Watts per hour // If this is too slow, make a power of 2 shit instead... tmp_energy.total=cummulative_energy.total/3600; tmp_energy2.total=cummulative_energy2.total/3600; // Only care about lower 6 bytes of 8 byte long long // At max power this will last 239 years // Divide by P-scaler to get Watt*hrs if(total_secs%400==0 ) { nrk_int_disable(); nrk_eeprom_write_byte(EEPROM_ENERGY1_0_ADDR, cummulative_energy.byte[0]); nrk_eeprom_write_byte(EEPROM_ENERGY1_1_ADDR, cummulative_energy.byte[1]); nrk_eeprom_write_byte(EEPROM_ENERGY1_2_ADDR, cummulative_energy.byte[2]); nrk_eeprom_write_byte(EEPROM_ENERGY1_3_ADDR, cummulative_energy.byte[3]); nrk_eeprom_write_byte(EEPROM_ENERGY1_4_ADDR, cummulative_energy.byte[4]); nrk_eeprom_write_byte(EEPROM_ENERGY1_5_ADDR, cummulative_energy.byte[5]); nrk_eeprom_write_byte(EEPROM_ENERGY1_6_ADDR, cummulative_energy.byte[6]); nrk_eeprom_write_byte(EEPROM_ENERGY1_7_ADDR, cummulative_energy.byte[7]); nrk_eeprom_write_byte(EEPROM_ENERGY2_0_ADDR, cummulative_energy2.byte[0]); nrk_eeprom_write_byte(EEPROM_ENERGY2_1_ADDR, cummulative_energy2.byte[1]); nrk_eeprom_write_byte(EEPROM_ENERGY2_2_ADDR, cummulative_energy2.byte[2]); nrk_eeprom_write_byte(EEPROM_ENERGY2_3_ADDR, cummulative_energy2.byte[3]); nrk_eeprom_write_byte(EEPROM_ENERGY2_4_ADDR, cummulative_energy2.byte[4]); nrk_eeprom_write_byte(EEPROM_ENERGY2_5_ADDR, cummulative_energy2.byte[5]); nrk_eeprom_write_byte(EEPROM_ENERGY2_6_ADDR, cummulative_energy2.byte[6]); nrk_eeprom_write_byte(EEPROM_ENERGY2_7_ADDR, cummulative_energy2.byte[7]); nrk_int_enable(); } /* // EVENT DETECTOR tran_pkt.msgs_payload=async_buf; tran_pkt.num_msgs=0; //if(rms_current>current_last) delta=rms_current-current_last; //else delta=current_last-rms_current; if(true_power>true_power_last) delta=true_power-true_power_last; else delta=true_power_last-true_power; if(true_power2>true_power_last2) delta2=true_power2-true_power_last2; else delta=true_power_last2-true_power2; //if(rms_current2>current_last2) delta2=rms_current2-current_last2; //else delta2=current_last2-rms_current2; if((socket_0_push_enabled && (delta>socket_0_push_threshold*100)) || (socket_1_push_enabled && (delta2>socket_1_push_threshold*100))) { pd_pkt.type=DEBUG_PKT; pd_pkt.rms_voltage=rms_voltage; pd_pkt.rms_current=rms_current; pd_pkt.rms_current2=rms_current2; pd_pkt.true_power=true_power; pd_pkt.true_power2=true_power2; pd_pkt.freq=freq; pd_pkt.socket0_state= socket_0_active; pd_pkt.socket1_state= socket_1_active; for(len=0; len<6; len++ ) { pd_pkt.energy[len]=tmp_energy.byte[len]; pd_pkt.energy2[len]=tmp_energy2.byte[len]; } pd_pkt.current_p2p_high=l_c_p2p_high; pd_pkt.current_p2p_low=l_c_p2p_low; pd_pkt.current_p2p_high2=l_c_p2p_high2; pd_pkt.current_p2p_low2=l_c_p2p_low2; pd_pkt.voltage_p2p_high=l_v_p2p_high; pd_pkt.voltage_p2p_low=l_v_p2p_low; pd_pkt.total_secs=total_secs; tran_pkt.num_msgs=0; tran_pkt.checksum=0; tran_pkt.msgs_payload=&(async_buf[TRANSDUCER_PKT_HEADER_SIZE]); tran_msg.payload=&(async_buf[TRANSDUCER_PKT_HEADER_SIZE+TRANSDUCER_MSG_HEADER_SIZE]); tran_msg.type=TRAN_POWER_PKT; tran_msg.len=ff_power_debug_pack(tran_msg.payload, &pd_pkt); tran_msg.mac_addr=my_mac; len=transducer_msg_add( &tran_pkt, &tran_msg); len = transducer_pkt_pack(&tran_pkt, async_buf); val=push_p2p_pkt( async_buf,len,TRANSDUCER_PKT, 0x0 ); } */ true_power_last=true_power; true_power_last2=true_power2; } // toggle RED led if freq not above 50Hz //if(freq==0) nrk_led_toggle(RED_LED); } }