static void vAppendData(xPollingFrame_t* frame, uint16_t data) { if (frame->index == 0) { frame->starttime[0] = (myTime >> 8) & 0xFF; frame->starttime[1] = myTime & 0xFF; frame->starttime[2] = (timerB_time() >> 8) & 0xFF; frame->starttime[3] = timerB_time() & 0xFF; }
static uint16_t beacon_sent(void) { beacon_eop_time = timerB_time(); LED_RED_OFF(); beacon_msg.seq++; cc1101_gdo0_register_callback(slot_data); LED_GREEN_ON(); return 0; }
uint16_t packet_error(uint8_t packet[]) { printf("[APP];SEND_PACKET_ERROR;%u-%u\n",global_clock, timerB_time()/32); return 1; }
uint16_t packet_sent(void) { printf("[APP];SEND_PACKET_DONE;%u-%u\n",global_clock, timerB_time()/32); return 1; }
uint16_t packet_received(uint8_t packet[], uint16_t length, uint16_t src_addr, int16_t rssi) { if (packet[0] == DATA) { if (type == SINK) { stat_add(STAT_APP_RX); printf("[APP];SINK_RX;%c%c%c%c;%.4x;%u;%u\n", packet[2], packet[3], packet[4], packet[5],src_addr, packet[6],packet[7]); return 0; } else { routing_txframe[0] = DATA; routing_txframe[1] = level-1; //node level routing_txframe[2] = packet[2]; //node id routing_txframe[3] = packet[3]; routing_txframe[4] = packet[4]; routing_txframe[5] = packet[5]; routing_txframe[6] = packet[6]; // num sequence routing_txframe[7] = packet[7] + 1; // nb hops txlength = 8; printf("[ROUTING];NODE_FORWARD;%.4x;%c%c%c%c;%u;%u;%u-%u\n", nodeaddr, routing_txframe[2], routing_txframe[3], routing_txframe[4], routing_txframe[5], routing_txframe[6],routing_txframe[7],global_clock, timerB_time()/32); stat_add(STAT_FORWARD_CNT); mac_send(routing_txframe, txlength, parent_id); } } return 0; }
int main(void) { WDTCTL = WDTPW+WDTHOLD; set_mcu_speed_xt2_mclk_8MHz_smclk_1MHz(); set_aclk_div(1); LEDS_INIT(); LEDS_OFF(); ds2411_init(); nodeaddr = (((uint16_t)ds2411_id.serial1)<<8) + (ds2411_id.serial0); uart0_init(UART0_CONFIG_1MHZ_115200); uart0_register_callback(char_rx); eint(); printf("[APP];BOOTING;%.4x\n",nodeaddr); //check if this node is the sink if (nodeaddr == sink_nodes) { type = SINK; level = DEFAULT_LEVEL; } else { //retrieve father for (idx=0; idx<NUMBER_NODES; idx++) { if (list_nodes[idx] == nodeaddr) { if(father_nodes1[idx] != 0x0000) { parent_id = father_nodes1[idx]; level = 12; break; } } } } //hack for mobile /*if(nodeaddr == 0x1f5d) { parent_id = 0x0000; mac_set_mobile(1); level = 12; }*/ mac_init(10); mac_set_rx_cb(packet_received); mac_set_error_cb(packet_error); mac_set_sent_cb(packet_sent); timerB_set_alarm_from_now(TIMERB_ALARM_CCR6, 32768, 32768); timerB_register_cb(TIMERB_ALARM_CCR6, inc_clock); while (1) { LPM1; if (state == SM_TX) { if (level != UNDEF_LEVEL && type != SINK) { seq_max = NUM_SEQ_MAX; delay = rand(); delay &= 0xCFFF; delay += 12000; //(369ms < delay < 1991ms) timerB_set_alarm_from_now(TIMERB_ALARM_CCR5, delay, 0); timerB_register_cb(TIMERB_ALARM_CCR5, next_send); } else { printf("[APP];NOROUTE\n"); } state = SM_IDLE; } else if (state == SM_LOOP_TX) { if (level != UNDEF_LEVEL) { sprintf(sourceaddr,"%.4x",nodeaddr); data_txframe[0] = DATA; data_txframe[1] = level-1; data_txframe[2] = sourceaddr[0]; data_txframe[3] = sourceaddr[1]; data_txframe[4] = sourceaddr[2]; data_txframe[5] = sourceaddr[3]; data_txframe[6] = seq; //sequence data_txframe[7] = 1; //hops txlength = 8; stat_add(STAT_APP_TX); printf("[APP];NODE_TX;%.4x;%.4x;%u;%u-%u\n", nodeaddr, parent_id, seq, global_clock, timerB_time()/32); seq++; mac_send(data_txframe, txlength, parent_id); if (DEBUG_LEDS == 1) { LED_GREEN_ON(); } if (seq < seq_max) { timerB_set_alarm_from_now(TIMERB_ALARM_CCR5, SEND_DATA_PERIOD, 0); timerB_register_cb(TIMERB_ALARM_CCR5, next_send); } } state = SM_IDLE; } } return 0; }
static uint16_t slot_data(void) { uint8_t len, src; uint16_t now; now = timerB_time(); // test CRC and bytes in FIFO len = cc1101_status_rxbytes(); // check fifo length if (len==0) { // empty packet //~ printf("empty"); return 0; } else if (len>64) { // overflow, flush //~ printf("over"); set_rx(); return 0; } // get length, and check cc1101_fifo_get(&data_msg.hdr.length, 1); if (data_msg.hdr.length>(DATA_LENGTH-1)) { // length too big, can't empty, flush //~ printf("big"); set_rx(); return 0; } // length is good // get data cc1101_fifo_get((uint8_t*)&data_msg+1, data_msg.hdr.length); // get status cc1101_fifo_get((uint8_t*)&footer, FOOTER_LENGTH); // check CRC if ( (footer.crc&0x80)==0 ) { // bad crc, exit //~ printf("crc"); return 0; } // check type, destination if (HEADER_GET_TYPE(data_msg.hdr) != DATA_TYPE) { //~ printf("not_data"); return 0; } // check source corresponds to timeslot src = HEADER_GET_ADDR(data_msg.hdr); if (tdma_mgt_getaddr(slot_count)!=src) { // src doesn't match slot return 0; } // check data has been read if (mac_slots[slot_count-1].ready==0) { memcpy(mac_slots[slot_count-1].data, data_msg.payload, MAC_PAYLOAD_SIZE); mac_slots[slot_count-1].ready = 1; // wake the CPU up by returning 1 return 1; } return 0; }