static void sniff_switch_channel(handler_arg_t arg) { phy_idle(platform_phy); // Select next channel do { radio.current_channel++; if (radio.current_channel > PHY_2400_MAX_CHANNEL) { radio.current_channel = PHY_2400_MIN_CHANNEL; } } while ((radio.channels & (1 << radio.current_channel)) == 0); // Enter RX on new channel phy_set_channel(platform_phy, radio.current_channel); phy_status_t ret = phy_rx(platform_phy, 0, soft_timer_time() + soft_timer_ms_to_ticks(500), radio.sniff.pkt_buf + radio.sniff.pkt_index, sniff_rx); if (ret != PHY_SUCCESS) { log_error("PHY RX Failed"); } log_debug("Sniff RX on channel %u", radio.current_channel); }
/**************************************************************** * Description: The TxInProgress bit is set when the mac_tx_data * function is called the first time to actually send the * packet. After that, each loop through the mac_tx_handler * checks to see if the TX started and finished correctly. * The FSM becomes idle if: * a. the PHY TX returns an error * b. the PHY TX returned success * c. the PHY TX returned failed and we exhausted retries. * * Arguments: * None. * Return: * None. * * Date: 2010-05-20 ****************************************************************/ static void mac_tx_handler() { // Ensure tx is in progress if(mac_tx_busy()) { // PHY layer has finish the tx if (phy_idle()) { // Copy the tx result a_mac_service.status = phy_tx_result(); #ifdef STATISTIC // If send success? if (a_mac_service.status == LRWPAN_STATUS_SUCCESS) statistic_mac_tx ++; else statistic_mac_err++; #endif // Set mac tx to idle mac_set_tx_idle(); mac_state = MAC_STATE_IDLE; // Change the mhr filled state, so we can // send data in the queue new_mhr_filled = FALSE; // Remove the data from queue queue_remove_next(&mac_send_queue); } } }
static void send_packet(handler_arg_t arg) { // Set IDLE phy_idle(platform_phy); // Prepare the packet and place phy_prepare_packet(&tx_packet); // Create a payload tx_packet.length = snprintf((char*) tx_packet.data, PHY_MAX_TX_LENGTH, "Packet from %02x:%02x:%02x, count=%u", uid->uid8[9], uid->uid8[10], uid->uid8[11], tx_count); // Perform a CCA int32_t cca; phy_cca(platform_phy, &cca); if (cca) { // Channel is clear // Send phy_tx_now(platform_phy, &tx_packet, tx_done); printf("Sending Packet, count=%u\n", tx_count); // Increment counter tx_count++; } else { printf("TX aborted, channel is busy\n"); enter_rx(NULL); } }
static void enter_rx(handler_arg_t arg) { // Set PHY IDLE, then enter RX phy_idle(platform_phy); phy_set_channel(platform_phy, RADIO_CHANNEL); // Prepare packet and start RX phy_prepare_packet(&rx_packet); phy_rx_now(platform_phy, &rx_packet, rx_done); }
static void restore_state(void) { // Reset old state switch (old_state) { case RX: phy_rx(); break; case IDLE: default: phy_idle(); break; } }
static void proper_stop() { // Stop timer soft_timer_stop(&radio.period_tim); // Set PHY idle phy_idle(platform_phy); // Free polling packet if (radio.poll.serial_pkt) { packet_free(radio.poll.serial_pkt); radio.poll.serial_pkt = NULL; } }
static void jam_change_channel_time(handler_arg_t arg) { // Increment channel do { radio.current_channel++; if (radio.current_channel > PHY_2400_MAX_CHANNEL) { radio.current_channel = PHY_2400_MIN_CHANNEL; } } while ((radio.channels & (1 << radio.current_channel)) == 0); // Re-Jam phy_idle(platform_phy); phy_jam(platform_phy, radio.current_channel, radio.jam.tx_power); log_info("Jamming on channel %u", radio.current_channel); }
static void tx(handler_arg_t arg) { static uint8_t count = 0; phy_idle(PHY); // Prepare packet pkt.data = pkt.raw_data; pkt.length = sizeof(msg); memcpy(pkt.data, msg, pkt.length); pkt.data[pkt.length - 4] = '0' + ((count / 100) % 10); pkt.data[pkt.length - 3] = '0' + ((count / 10) % 10); pkt.data[pkt.length - 2] = '0' + ((count / 1) % 10); count ++; // Send in 10ms, no handler printf("Sending a Radio Packet, length: %u, data: %s\n", pkt.length, pkt.data); uint32_t t = soft_timer_time() + soft_timer_ms_to_ticks(10); phy_tx(PHY, t, &pkt, tx_done); }
static void scan_timeout() { if (dll_state == DllStateNone) return; #ifdef LOG_DLL_ENABLED log_print_stack_string(LOG_DLL, "DLL scan time-out"); #endif phy_idle(); if (current_css == NULL) { return; } //Channel scan series timer_event event; event.next_event = current_css->values[current_scan_id].time_next_scan; event.f = &scan_next; current_scan_id = current_scan_id < current_css->length - 1 ? current_scan_id + 1 : 0; timer_add_event(&event); }
static char *radio_pkt(uint8_t channel, uint8_t tx_power) { static phy_packet_t tx_pkt = { .data = tx_pkt.raw_data, .length = 125, }; uint16_t i; for (i = 0; i < 125; i++) { tx_pkt.data[i] = i; } int success; char *ret = NULL; xQueueReceive(radio_queue, &success, 0); // cleanup queue phy_idle(platform_phy); /* * config radio */ if (phy_set_channel(platform_phy, channel)) ON_ERROR("err_set_channel", radio_cleanup); if (phy_set_power(platform_phy, tx_power)) ON_ERROR("err_set_power", radio_cleanup); /* * Send packet * * No interlocking because * Current queue is EVENT_QUEUE_APPLI * phy_ handlers are executed by EVENT_QUEUE_NETWORK */ if (phy_tx_now(platform_phy, &tx_pkt, radio_rx_tx_done)) ON_ERROR("err_tx", radio_cleanup); if (pdTRUE != xQueueReceive(radio_queue, &success, ONE_SECOND) || !success) ON_ERROR("tx_failed", radio_cleanup); // SUCCESS radio_cleanup: phy_reset(platform_phy); return ret; } static char *radio_ping_pong(uint8_t channel, uint8_t tx_power) { char *ret = NULL; int success; static phy_packet_t tx_pkt = { .data = tx_pkt.raw_data, .length = sizeof(RADIO_TX_STR), .raw_data = RADIO_TX_STR, }; static phy_packet_t rx_pkt = {.data = rx_pkt.raw_data}; xQueueReceive(radio_queue, &success, 0); // cleanup queue phy_idle(platform_phy); /* config radio */ if (phy_set_channel(platform_phy, channel)) ON_ERROR("err_set_channel", ping_pong_cleanup); if (phy_set_power(platform_phy, tx_power)) ON_ERROR("err_set_power", ping_pong_cleanup); /* * Send packet * * No interlocking because * Current queue is EVENT_QUEUE_APPLI * phy_ handlers are executed by EVENT_QUEUE_NETWORK */ if (phy_tx_now(platform_phy, &tx_pkt, radio_rx_tx_done)) ON_ERROR("err_tx", ping_pong_cleanup); if (pdTRUE != xQueueReceive(radio_queue, &success, ONE_SECOND) || !success) ON_ERROR("tx_failed", ping_pong_cleanup); /* * Wait for answer */ memset(rx_pkt.raw_data, 0, sizeof(rx_pkt.raw_data)); phy_rx_now(platform_phy, &rx_pkt, radio_rx_tx_done); if (pdTRUE != xQueueReceive(radio_queue, &success, ONE_SECOND) || !success) ON_ERROR("rx_timeout", ping_pong_cleanup); // Packet reception if (strcmp("RX_PKT_HELLO_WORLD", (char *)rx_pkt.raw_data)) ON_ERROR("wrong_packet_received", ping_pong_cleanup); // SUCCESS ret = NULL; ping_pong_cleanup: phy_reset(platform_phy); return ret; } #ifdef IOTLAB_M3 //////// static int test_flash_nand() { static uint8_t buf_EE[256] = {[0 ... 255] = 0xEE}; static uint8_t buf[256] = {[0 ... 255] = 0x00}; // Write subsector 200 and re-read it n25xxx_write_enable(); n25xxx_erase_subsector(0x00c80000); n25xxx_write_enable(); n25xxx_write_page(0x00c80000, buf_EE); n25xxx_read(0x00c80000, buf, sizeof(buf)); n25xxx_write_enable(); n25xxx_erase_subsector(0x00c80000); // check read values return memcmp(buf_EE, buf, sizeof(buf)); } //////// static int cmd_get_light(char *command) { if (strcmp(command, "get_light")) return 1; printf("ACK get_light %f lux\n", isl29020_read_sample()); return 0; } static int cmd_get_pressure(char *command) { if (strcmp(command, "get_pressure")) return 1; uint32_t pressure; lps331ap_read_pres(&pressure); printf("ACK get_pressure %f mbar\n", pressure / 4096.0); return 0; } static int cmd_test_flash_nand(char *command) { if (strcmp(command, "test_flash")) return 1; if (test_flash_nand()) printf("NACK test_flash read_different_write\n"); else printf("ACK test_flash\n"); return 0; } #endif // IOTLAB_M3 /* Leds Commands */ static int cmd_leds_on(char *command) { uint8_t leds = 0; if (1 != sscanf(command, "leds_on %u", &leds)) return 1; leds_on(leds); printf("ACK leds_on %x\n", leds); return 0; } static int cmd_leds_off(char *command) { uint8_t leds = 0; if (1 != sscanf(command, "leds_off %u", &leds)) return 1; leds_off(leds); printf("ACK leds_off %x\n", leds); return 0; }
void start_tx(void) { phy_idle(); phy_tx(&tx_cfg); }