void radio_hdlr(uint8_t evt, void *data) { struct radio_packet *packet = data; if (evt != RADIO_EVT_RX_COMPLETED) { ERROR("Unexpected radio evt: %u", evt); return; } if (!packet->crcstatus) { DBG("ch %u bad crc", channels[idx]); goto recv; } /* Link Layer specification section 2.3, Core 4.1, page 2505 * * The length is the 6 LSB, and the minimum allowed payload is 6 bytes. */ if ((packet->pdu[1] & 0x3F) < 6) { DBG("ch %u bad length", channels[idx]); goto recv; } DBG("ch %u (%s)", channels[idx], format_address(data + 2)); recv: radio_recv(channels[idx], ADV_CHANNEL_AA, ADV_CHANNEL_CRC); }
void scan_interval_timeout(void *user_data) { idx = (idx + 1) % sizeof(channels); radio_recv(channels[idx], ADV_CHANNEL_AA, ADV_CHANNEL_CRC); timer_start(scan_window, SCAN_WINDOW, NULL); }
/** Callback function for the "interval" LL timer */ static void t_ll_interval_cb(void) { switch(current_state) { case LL_STATE_ADVERTISING: adv_ch_idx = first_adv_ch_idx(); t_ll_single_shot_cb(); break; case LL_STATE_SCANNING: if(!inc_adv_ch_idx()) adv_ch_idx = first_adv_ch_idx(); radio_prepare(adv_chs[adv_ch_idx], LL_ACCESS_ADDRESS_ADV, LL_CRCINIT_ADV); radio_recv(0); timer_start(t_ll_single_shot, t_scan_window); break; case LL_STATE_INITIATING: case LL_STATE_CONNECTION: /* Not implemented */ case LL_STATE_STANDBY: default: /* Nothing to do */ return; } }
int main() { log_serial = new Serial(DEBUG_TX, DEBUG_RX); log_serial->baud(9600); DigitalIn sw2(SW2); DigitalIn sw3(SW3); for (int i = 0; i < SERVO_COUNT; i++) { paint_heads[i] = PAINT_NEUTRAL; } radio_init(1500); const uint64_t remote_addr64 = UINT64(0x0013A200, 0x40d4f162); const XBeeLib::RemoteXBeeZB remoteDevice = XBeeLib::RemoteXBeeZB( remote_addr64); packet pkt; const char *data = "what's up man?"; strncpy((char *) &pkt.data, data, 100); pkt.len = strlen(data); radio_send(pkt); radio_bcast(pkt); radio_send(pkt, remoteDevice); uint8_t current_head = 0; log_serial->printf("Hello!\r\n"); while (true) { packet pkt; if (radio_recv(pkt, 0)) { printf( "\r\nGot a %s RX packet [%08lx:%08lx|%04x], " "len %d\r\nData: ", pkt.broadcast ? "BROADCAST" : "UNICAST", uint32_t (pkt.remote_addr64 >> 32), uint32_t (pkt.remote_addr64 & 0xFFFFFFFF), pkt.remote_addr16, pkt.len); printf("%.*s\r\n", pkt.len, pkt.data); } if (sw2 == 0) { printf("painting\r\n"); while (sw2 == 0); paint_heads[current_head % SERVO_COUNT] = PAINT_SPRAY; wait(PAINT_TIME); paint_heads[current_head % SERVO_COUNT] = PAINT_NEUTRAL; } if (sw3 == 0) { printf("head %d\r\n", current_head); current_head++; while (sw3 == 0); } }
/**@brief Function called by the radio driver (PHY layer) on packet RX * Dispatch the event according to the LL state */ static void ll_on_radio_rx(const uint8_t *pdu, bool crc, bool active) { struct ll_pdu_adv *rcvd_pdu = (struct ll_pdu_adv*) pdu; switch(current_state) { case LL_STATE_SCANNING: if(!ll_adv_report_cb) { ERROR("No adv. report callback defined"); return; } /* Extract information from PDU and call * ll_adv_report_cb */ ll_adv_report_cb(rcvd_pdu->type, rcvd_pdu->tx_add, rcvd_pdu->payload, rcvd_pdu->length - BDADDR_LEN, rcvd_pdu->payload + BDADDR_LEN); /* Receive new packets while the radio is not explicitly * stopped */ radio_recv(0); break; case LL_STATE_ADVERTISING: if (pdu_adv.type != LL_PDU_ADV_IND && pdu_adv.type != LL_PDU_ADV_SCAN_IND) break; if (rcvd_pdu->type != LL_PDU_SCAN_REQ) break; timer_stop(t_ll_ifs); send_scan_rsp(rcvd_pdu); break; case LL_STATE_INITIATING: case LL_STATE_CONNECTION: case LL_STATE_STANDBY: default: /* Nothing to do */ return; } }
int main(void) { log_init(); timer_init(); radio_init(radio_hdlr); scan_window = timer_create(TIMER_SINGLESHOT, scan_window_timeout); scan_interval = timer_create(TIMER_REPEATED, scan_interval_timeout); radio_recv(channels[idx], ADV_CHANNEL_AA, ADV_CHANNEL_CRC); timer_start(scan_window, SCAN_WINDOW, NULL); timer_start(scan_interval, SCAN_INTERVAL, NULL); while (1); return 0; }
void *th_recv( void *arg ){ my_info_t *buf; rf_pkt recv_buf; uint8_t i; while(1){ if( radio_recv(RADIO_PORT, (rf_pkt*)&recv_buf ) > 0 ){ buf = (my_info_t*)&recv_buf; uint8_t idx = buf->id; pthread_mutex_lock( &mutex_lock ); nb_table[idx].x = buf->x; nb_table[idx].y = buf->y; nb_table[idx].d = ptod( nb_table[LOCAL_ADDR].x, nb_table[LOCAL_ADDR].y, nb_table[idx].x, nb_table[idx].y ); if( nb_table[idx].life < 5 ) nb_table[idx].life++; pthread_mutex_unlock( &mutex_lock ); led2_toggle(); } else continue; uint8_t cnt = 0; for( i = 0; i < MAX_NB_CNT; i++ ){ if( nb_table[i].life > 0 ) cnt++; } if( cnt >= 3 ){ my_info.level = MTSL_LEVEL3; } } }