/** \copydoc nwl_build_advp_sync_train */ void nwl_build_advp_sync_train(uint16_t duration, uint8_t spectrum_id[2], int8_t tx_eirp, uint8_t subnet) { uint16_t advp_target_timestamp = timer_get_counter_value() + duration; phy_keep_radio_on(true); process_callback = false; uint16_t eta = duration; //advp_target_timestamp - timer_get_counter_value(); //nwl_event.next_event = while (eta > 5 && eta <= duration) { tx_callback_received = false; nwl_build_advertising_protocol_data(eta, spectrum_id, tx_eirp, subnet); dll_tx_frame(); while (!tx_callback_received); __delay_cycles(8000); eta = advp_target_timestamp - timer_get_counter_value(); } phy_keep_radio_on(false); process_callback = true; }
static void configure_next_event() { //this function should only be called from an atomic context timer_tick_t next_fire_time; do { //find the next event that has not yet passed, and schedule //the 'late' events while we're at it NG(next_event) = get_next_event(); if(NG(next_event) != NO_EVENT) { next_fire_time = NG(timers)[NG(next_event)].next_event; if ( (((int32_t)next_fire_time) - ((int32_t)timer_get_counter_value())) <= 0 ) { sched_post_task_prio(NG(timers)[NG(next_event)].f, NG(timers)[NG(next_event)].priority); NG(timers)[NG(next_event)].f = 0x0; } } } while(NG(next_event) != NO_EVENT && ( (((int32_t)next_fire_time) - ((int32_t)timer_get_counter_value())) <= 0 ) ); //at this point NG(next_event) is eiter equal to NO_EVENT (no tasks left) //or we have the next event we can schedule if(NG(next_event) == NO_EVENT) { //cancel the timer in case it is still running (can happen if we're called from timer_cancel_event) NG(hw_event_scheduled) = false; hw_timer_cancel(HW_TIMER_ID); } else { //calculate schedule time relative to current time rather than //latest overflow time, to counteract any delays in updating counter_offset //(eg when we're scheduling an event from an interrupt and thereby delaying //the updating of counter_offset) timer_tick_t fire_delay = (next_fire_time - timer_get_counter_value()); //if the timer should fire in less ticks than supported by the HW timer --> schedule it //(otherwise it is scheduled from timer_overflow when needed) if(fire_delay < COUNTER_OVERFLOW_INCREASE) { NG(hw_event_scheduled) = true; hw_timer_schedule_delay(HW_TIMER_ID, (hwtimer_tick_t)fire_delay); #ifndef NDEBUG //check that we didn't try to schedule a timer in the past //normally this shouldn't happen but it IS theoretically possible... fire_delay = (next_fire_time - timer_get_counter_value()); //fire_delay should be in [0,COUNTER_OVERFLOW_INCREASE]. if this is not the case, it is because timer_get_counter() is //now larger than next_fire_event, which means we 'missed' the event assert(((int32_t)fire_delay) > 0); #endif } else { //set hw_event_scheduled explicitly to false to allow timer_overflow //to schedule the event when needed NG(hw_event_scheduled) = false; } } }
void bootstrap() { log_print_string("Device booted at time: %d\n", timer_get_counter_value()); hw_radio_init(p_alloc, p_free); hw_radio_set_rx(&rx_cfg, rx_callback, rssi_valid); NG(tx_buffer).radio_packet.length = sizeof(packet_struct_t) - sizeof(hw_radio_packet_t); NG(tx_buffer).radio_packet.tx_meta.tx_cfg.channel_id = rx_cfg.channel_id; NG(tx_buffer).radio_packet.tx_meta.tx_cfg.syncword_class = rx_cfg.syncword_class; NG(tx_buffer).radio_packet.tx_meta.tx_cfg.eirp = 0; NG(tx_buffer).src_node = hw_get_unique_id(); NG(tx_buffer).dst_node = 0xFFFF; NG(tx_buffer).counter = 0; sched_register_task(&send_packet); timer_post_task_delay(&send_packet, TIMER_TICKS_PER_SEC + (get_rnd() %TIMER_TICKS_PER_SEC)); // NG(status).is_rx = false; // NG(status).is_sleep = true; // NG(status).tx_busy = false; // NG(status).rx_busy = false; // sched_register_task(&poll_status); // sched_post_task(poll_status); }
void bootstrap() { DPRINT("Device booted at time: %d\n", timer_get_counter_value()); // TODO not printed for some reason, debug later id = hw_get_unique_id(); hw_radio_init(&alloc_new_packet, &release_packet); rx_cfg.channel_id = current_channel_id; tx_cfg.channel_id = current_channel_id; ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); fifo_init(&uart_rx_fifo, uart_rx_buffer, sizeof(uart_rx_buffer)); uart_set_rx_interrupt_callback(&uart_rx_cb); uart_rx_interrupt_enable(true); sched_register_task(&start_rx); sched_register_task(&transmit_packet); sched_register_task(&start); sched_register_task(&process_uart_rx_fifo); current_state = STATE_CONFIG_DIRECTION; sched_post_task(&start); sched_post_task(&process_uart_rx_fifo); }
void bootstrap() { led_on(0); led_on(1); log_print_string("Device booted at time: %d\n", timer_get_counter_value()); console_print("Device Booted\r\n"); sched_register_task(&led_on_callback); sched_register_task(&led_off_callback); sched_register_task(&timer1_callback); timer_post_task_delay(&led_on_callback, TIMER_TICKS_PER_SEC); //timer_post_task_delay(&timer1_callback, 0x0000FFFF + (uint32_t)100); #if PLATFORM_NUM_BUTTONS > 0 int i= 0; for (i=0;i<PLATFORM_NUM_BUTTONS;i++) { ubutton_register_callback(i, &userbutton_callback); } #endif led_off(0); led_off(1); }
/** * Get the current counter value between 0 and the maximum count (HAL_timer_set_count) * @param timer_num timer number to get the current count * @return the current counter of the alarm */ hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { const tTimerConfig timer = TimerConfig[timer_num]; uint64_t counter_value; timer_get_counter_value(timer.group, timer.idx, &counter_value); return counter_value; }
static void process_serial_frame(fifo_t* fifo) { bool command_completed = false; bool completed_with_error = false; while(fifo_get_size(fifo)) { alp_action_t action; alp_parse_action(fifo, &action); switch(action.operation) { case ALP_OP_RETURN_TAG: if(action.tag_response.tag_id == command.tag_id) { command_completed = action.tag_response.completed; completed_with_error = action.tag_response.error; } else { DPRINT("received resp with unexpected tag_id (%i vs %i)", action.tag_response.tag_id, command.tag_id); // TODO unsolicited responses } break; case ALP_OP_WRITE_FILE_DATA: if(callbacks->write_file_data_callback) callbacks->write_file_data_callback(action.file_data_operand.file_offset.file_id, action.file_data_operand.file_offset.offset, action.file_data_operand.provided_data_length, action.file_data_operand.data); break; case ALP_OP_RETURN_FILE_DATA: if(callbacks->return_file_data_callback) callbacks->return_file_data_callback(action.file_data_operand.file_offset.file_id, action.file_data_operand.file_offset.offset, action.file_data_operand.provided_data_length, action.file_data_operand.data); break; case ALP_OP_RETURN_STATUS: if(action.status.type==ALP_ITF_ID_D7ASP) { d7ap_session_result_t interface_status = *((d7ap_session_result_t*)action.status.data); uint8_t addressee_len = d7ap_addressee_id_length(interface_status.addressee.ctrl.id_type); DPRINT("received resp from: "); DPRINT_DATA(interface_status.addressee.id, addressee_len); } if(callbacks->modem_interface_status_callback) callbacks->modem_interface_status_callback(action.status.type,&action.status.data); break; default: assert(false); } } if(command_completed) { DPRINT("command with tag %i completed @ %i", command.tag_id, timer_get_counter_value()); if(callbacks->command_completed_callback) callbacks->command_completed_callback(completed_with_error,command.tag_id); command.is_active = false; } }
void execute_sensor_measurement() { #if HW_NUM_LEDS >= 1 led_toggle(0); #endif // use the counter value for now instead of 'real' sensor uint32_t val = timer_get_counter_value(); // file 0x40 is configured to use D7AActP trigger an ALP action which // broadcasts this file data on Access Class 0 fs_write_file(0x40, 0, (uint8_t*)&val, 4); timer_post_task_delay(&execute_sensor_measurement, REPORTING_INTERVAL_TICKS); }
void read_rssi() { timestamped_rssi_t rssi_measurement; rssi_measurement.tick = timer_get_counter_value(); rssi_measurement.rssi = hw_radio_get_rssi(); rssi_measurements[rssi_measurements_index] = rssi_measurement; rssi_measurements_index++; if(rssi_measurements_index < 1000) timer_post_task_delay(&read_rssi, 1); // TODO delay else log_print_string("done"); }
static void rx_callback(hw_radio_packet_t* tx_packet) { if(tx_packet->length < sizeof(packet_struct_t) - sizeof(hw_radio_packet_t)) log_print_string("Got an invalid packet at time %d: packet was too short: %d < %d", timer_get_counter_value(), tx_packet->length, sizeof(packet_struct_t)); else { packet_struct_t* packet = (packet_struct_t*)tx_packet; if(packet->radio_packet.length != sizeof(packet_struct_t) - sizeof(hw_radio_packet_t)) log_print_string("Got an invalid packet at time %d: packet length didn't match", timer_get_counter_value()); log_print_string("Got packet from %u to %u, seq: %u at time %u", packet->src_node, packet->dst_node, packet->counter, timer_get_counter_value()); } p_free(tx_packet); }
__LINK_C error_t timer_post_task_prio(task_t task, timer_tick_t fire_time, uint8_t priority) { error_t status = ENOMEM; if(priority > MIN_PRIORITY) return EINVAL; start_atomic(); uint32_t empty_index = FRAMEWORK_TIMER_STACK_SIZE; for(uint32_t i = 0; i < FRAMEWORK_TIMER_STACK_SIZE; i++) { if(NG(timers)[i].f == 0x0 && empty_index == FRAMEWORK_TIMER_STACK_SIZE) { empty_index = i; } else if(NG(timers)[i].f == task) { //for now: do not allow an event to be scheduled more than once //otherwise we risk having the same task being scheduled twice and only executed once //because the scheduler disallows the same task to be scheduled multiple times status = EALREADY; break; } } if(status != EALREADY && empty_index != FRAMEWORK_TIMER_STACK_SIZE) { bool timers_reset = reset_timers(); NG(timers)[empty_index].f = task; NG(timers)[empty_index].next_event = fire_time; NG(timers)[empty_index].priority = priority; //if there is no event scheduled, this event will run before the next scheduled event //or we reset the timers: trigger a reconfiguration of the next scheduled event bool do_config = NG(next_event) == NO_EVENT || timers_reset; if(!do_config) { uint32_t counter = timer_get_counter_value(); //if the new event should fire sooner than the old event --> trigger reconfig //this is done using signed ints (compared to the current counter) //to ensure propper handling of timer overflows int32_t next_fire_delay = ((int32_t)fire_time) - ((int32_t)counter); int32_t old_fire_delay = ((int32_t)NG(timers)[NG(next_event)].next_event) - ((int32_t)counter); do_config = next_fire_delay < old_fire_delay; } if(do_config) configure_next_event(); status = SUCCESS; } end_atomic(); return status; }
bool alloc_command() { if(command.is_active) { DPRINT("prev command still active @ %i", timer_get_counter_value()); return false; } command.is_active = true; fifo_init(&command.fifo, command.buffer, CMD_BUFFER_SIZE); command.tag_id = next_tag_id; next_tag_id++; alp_append_tag_request_action(&command.fifo, command.tag_id, true); return true; }
void bootstrap() { DPRINT("Device booted at time: %d\n", timer_get_counter_value()); #ifndef FRAMEWORK_LOG_BINARY console_print("\r\nPER TEST - commands:\r\n"); console_print(" CHANfffriii channel settings:\r\n"); console_print(" fff frequency : 433, 868, 915\r\n"); console_print(" r rate : L(ow) N(ormal) H(igh)\r\n"); console_print(" iii center_freq_index\r\n"); console_print(" TRANsss transmit a packet every sss seconds.\r\n"); console_print(" RECV receive packets\r\n"); console_print(" RSET reset module\r\n"); #endif id = hw_get_unique_id(); hw_radio_init(&alloc_new_packet, &release_packet); rx_cfg.channel_id = current_channel_id; tx_cfg.channel_id = current_channel_id; ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); fifo_init(&uart_rx_fifo, uart_rx_buffer, sizeof(uart_rx_buffer)); console_set_rx_interrupt_callback(&uart_rx_cb); console_rx_interrupt_enable(); sched_register_task(&start_rx); sched_register_task(&transmit_packet); sched_register_task(&start); sched_register_task(&process_uart_rx_fifo); current_state = STATE_CONFIG_DIRECTION; sched_post_task(&start); sched_post_task(&process_uart_rx_fifo); #ifdef PLATFORM_EFM32GG_STK3700 #else char str[20]; channel_id_to_string(¤t_channel_id, str, sizeof(str)); lcd_write_line(6, str); #endif timer_post_task(&transmit_packet, TIMER_TICKS_PER_SEC * 1); }
void read_rssi() { timestamped_rssi_t rssi_measurement; rssi_measurement.tick = timer_get_counter_value(); char rssi_samples_str[5 * RSSI_SAMPLES_PER_MEASUREMENT] = ""; int16_t max_rssi_sample = -200; for(int i = 0; i < RSSI_SAMPLES_PER_MEASUREMENT; i++) { rssi_measurement.rssi[i] = hw_radio_get_rssi(); if(rssi_measurement.rssi[i] > max_rssi_sample) max_rssi_sample = rssi_measurement.rssi[i]; sprintf(rssi_samples_str + (i * 5), ",%04i", rssi_measurement.rssi[i]); // TODO delay? } char str[80]; char channel_str[8] = ""; channel_id_to_string(&rx_cfg.channel_id, channel_str, sizeof(channel_str)); lcd_write_string(channel_str); sprintf(str, "%7s,%i%s\n", channel_str, rssi_measurement.tick, rssi_samples_str); console_print(str); #ifdef PLATFORM_EFM32GG_STK3700 //lcd_all_on(); lcd_write_number(max_rssi_sample); #elif defined HAS_LCD sprintf(str, "%7s,%d\n", channel_str, max_rssi_sample); lcd_write_string(str); #endif if(!use_manual_channel_switching) { switch_next_channel(); sched_post_task(&start_rx); } else { sched_post_task(&process_uart_rx_fifo); // check for UART commands first uint16_t delay = rand() % 5000; timer_post_task_delay(&read_rssi, delay); } hw_watchdog_feed(); }
static void ezradio_handle_end_of_packet() { // fill rx_meta rx_packet->rx_meta.rssi = hw_radio_get_latched_rssi(); rx_packet->rx_meta.lqi = 0; memcpy(&(rx_packet->rx_meta.rx_cfg.channel_id), ¤t_channel_id, sizeof(channel_id_t)); if (has_hardware_crc && current_rx_cfg.channel_id.channel_header.ch_coding != PHY_CODING_FEC_PN9) rx_packet->rx_meta.crc_status = HW_CRC_VALID; else rx_packet->rx_meta.crc_status = HW_CRC_UNAVAILABLE; rx_packet->rx_meta.timestamp = timer_get_counter_value(); //memcpy((void*)rx_packet->rx_meta.rx_cfg, (void*)¤t_rx_cfg, sizeof(hw_rx_metadata_t)); ezradio_fifo_info(EZRADIO_CMD_FIFO_INFO_ARG_FIFO_RX_BIT, NULL); DPRINT_DATA(rx_packet->data, rx_packet->length+1); if (current_rx_cfg.channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { fec_decode_packet(rx_packet->data, rx_packet->length, rx_packet->length); //assert length and data[0] can only differ 1 rx_packet->length = rx_packet->data[0]; } DPRINT_PACKET(rx_packet, false); DEBUG_RX_END(); // if(rx_packet_callback != NULL) // TODO this can happen while doing CCA but we should not be interrupting here (disable packet handler?) rx_packet_callback(rx_packet); // else // release_packet_callback(packet); if(current_state == HW_RADIO_STATE_RX) { start_rx(¤t_rx_cfg); } }
void bootstrap() { DPRINT("Device booted at time: %d\n", timer_get_counter_value()); // TODO not printed for some reason, debug later data[0] = PACKET_LENGTH-1; int i = 1; for (;i<PACKET_LENGTH;i++) data[i] = i; hw_radio_init(&alloc_new_packet, &release_packet); tx_packet->tx_meta.tx_cfg = tx_cfg; #ifdef RX_MODE sched_register_task(&start_rx); sched_post_task(&start_rx); #else sched_register_task(&transmit_packet); sched_post_task(&transmit_packet); #endif }
void measureTemperature() { float temp = hw_get_internal_temperature(); int temperature = (int)(temp * 10); #ifdef PLATFORM_EFM32GG_STK3700 int ring_segments = temperature/100; ring_segments = ring_segments > 8 ? 8 : ring_segments; lcd_show_ring(ring_segments); lcd_write_temperature(temperature*10, 1); #endif timer_tick_t tick = timer_get_counter_value(); char str[80]; sprintf(str, "%7s,%i,%2d.%2d\n", TEMPERATURE_TAG, tick, (temperature/10), abs(temperature%10)); console_print(str); }
//we override __assert_func to flash the leds (so we know something bad has happend) //and to repeat the error message repeatedly (so we have a chance to attach the device to a serial console before the error message is gone) void __assert_func( const char *file, int line, const char *func, const char *failedexpr) { #if defined FRAMEWORK_DEBUG_ASSERT_REBOOT // make sure this parameter is used also when including assert.h instead of debug.h hw_reset(); #endif start_atomic(); led_on(0); led_on(1); #ifdef PLATFORM_USE_USB_CDC // Dissable all IRQs except the one for USB for(uint32_t j=0;j < EMU_IRQn; j++) NVIC_DisableIRQ(j); NVIC_EnableIRQ( USB_IRQn ); end_atomic(); #endif lcd_clear(); lcd_write_string("ERROR"); lcd_write_number(timer_get_counter_value()); __asm__("BKPT"); // break into debugger while(1) { printf("assertion \"%s\" failed: file \"%s\", line %d%s%s\n",failedexpr, file, line, func ? ", function: " : "", func ? func : ""); for(uint32_t j = 0; j < 20; j++) { //blink at twice the frequency of the _exit call, so we can identify which of the two events has occurred for(uint32_t i = 0; i < 0xFFFFF; i++){} led_toggle(0); led_toggle(1); } } end_atomic(); }
void bootstrap() { DPRINT("Device booted at time: %d\n", timer_get_counter_value()); // TODO not printed for some reason, debug later #ifdef HAS_LCD lcd_write_string("cont tx"); #endif switch(current_channel_class) { // TODO only 433 for now case PHY_CLASS_NORMAL_RATE: channel_count = NORMAL_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i * 8; break; case PHY_CLASS_LO_RATE: channel_count = LO_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i; break; } #if NUM_USERBUTTONS > 1 ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); #endif hw_radio_init(NULL, NULL); sched_register_task(&start); timer_post_task_delay(&start, TIMER_TICKS_PER_SEC * 5); }
void bootstrap() { DPRINT("Device booted at time: %d\n", timer_get_counter_value()); // TODO not printed for some reason, debug later #ifdef HAS_LCD lcd_write_string("cont TX \n"); #endif switch(current_channel_class) { case PHY_CLASS_NORMAL_RATE: channel_count = NORMAL_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i * 8; break; case PHY_CLASS_LO_RATE: channel_count = LO_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i; break; } #if PLATFORM_NUM_BUTTONS > 1 ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); #endif hw_radio_init(&alloc_packet_callback, &release_packet_callback); sched_register_task(&start); timer_post_task_delay(&start, 500); }
static uint32_t get_next_event() { //this function should only be called from an atomic context reset_timers(); int32_t min_delay; uint32_t next_fire_event = NO_EVENT; uint32_t counter = timer_get_counter_value(); for(uint32_t i = 0; i < FRAMEWORK_TIMER_STACK_SIZE; i++) { if(NG(timers)[i].f == 0x0) continue; //trick borrowed from AODV: by using signed integers in this way //we know that if the event has already passed delay_ticks will be < 0 // --> events are sorted from past -> future regardless of any (pending) overflows int32_t delay_ticks = ((int32_t)NG(timers)[i].next_event) - ((int32_t)counter); if(next_fire_event == NO_EVENT || delay_ticks < min_delay) { min_delay = delay_ticks; next_fire_event = i; } } return next_fire_event; }
static bool reset_timers() { //this function should only be called from an atomic context if(NG(next_event) == NO_EVENT) { reset_counter(); return true; } timer_tick_t cur_value = timer_get_counter_value(); reset_counter(); for(uint32_t i = 0; i < FRAMEWORK_TIMER_STACK_SIZE; i++) { if(NG(timers)[i].f != 0x0) { //prevent the value from 'underflowing' if(cur_value > NG(timers)[i].next_event) NG(timers)[i].next_event = 0; else NG(timers)[i].next_event -= cur_value; } } return true; }
void bootstrap() { led_on(0); led_on(1); log_print_string("Device booted at time: %d\n", timer_get_counter_value()); sched_register_task(&led_on_callback); sched_register_task(&led_off_callback); sched_register_task(&timer1_callback); timer_post_task_delay(&led_on_callback, TIMER_TICKS_PER_SEC); timer_post_task_delay(&timer1_callback, 0x0000FFFF + (uint32_t)100); #if NUM_USERBUTTONS > 0 ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); #endif led_off(0); led_off(1); }
static void ezradio_int_callback() { //DPRINT("ezradio ISR"); ezradio_cmd_reply_t ezradioReply; ezradio_cmd_reply_t radioReplyLocal; ezradio_get_int_status(0x0, 0x0, 0x0, &ezradioReply); //ezradio_frr_a_read(3, &ezradioReply); //DPRINT(" - INT_PEND %s", byte_to_binary(ezradioReply.FRR_A_READ.FRR_A_VALUE)); DPRINT(" - INT_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.INT_PEND)); // DPRINT(" - INT_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.INT_STATUS)); // DPRINT(" - PH_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.PH_PEND)); //DPRINT(" - PH_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.PH_STATUS)); //DPRINT(" - PH_STATUS %s", byte_to_binary(ezradioReply.FRR_A_READ.FRR_B_VALUE)); // DPRINT(" - MODEM_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.MODEM_PEND)); // DPRINT(" - MODEM_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.MODEM_STATUS)); // DPRINT(" - CHIP_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.CHIP_PEND)); // DPRINT(" - CHIP_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.CHIP_STATUS)); //if (ezradioReply.FRR_A_READ.FRR_A_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_PH_INT_PEND_BIT) if (ezradioReply.GET_INT_STATUS.INT_PEND & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_PH_INT_PEND_BIT) { //DPRINT("PH ISR"); switch(current_state) { case HW_RADIO_STATE_RX: if ((ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_PACKET_RX_BIT) || (ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_RX_FIFO_ALMOST_FULL_BIT)) { //DPRINT("PACKET_RX IRQ"); if(rx_packet_callback != NULL) { /* Check how many bytes we received. */ ezradio_fifo_info(0, &radioReplyLocal); DPRINT("RX ISR packetLength: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); if (rx_fifo_data_lenght == 0) { DPRINT("RX FIFO: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); uint8_t buffer[4]; ezradio_read_rx_fifo(4, buffer); if (current_rx_cfg.channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { uint8_t fec_buffer[4]; memcpy(fec_buffer, buffer, 4); fec_decode_packet(fec_buffer, 4, 4); expected_data_length = fec_calculated_decoded_length(fec_buffer[0]+1); DPRINT("RX Packet Length: %d / %d", fec_buffer[0], expected_data_length); } else { expected_data_length = buffer[0] + 1; } rx_packet = alloc_packet_callback(expected_data_length); memcpy(rx_packet->data, buffer, 4); rx_fifo_data_lenght += 4; radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT-=4; } if (ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_PACKET_RX_BIT) { /* Read out the RX FIFO content. */ ezradio_read_rx_fifo(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT, &(rx_packet->data[rx_fifo_data_lenght])); //ezradio_read_rx_fifo(radioReplyLocal2.PACKET_INFO.LENGTH, packet->data); ezradio_handle_end_of_packet(); return; } if (ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_RX_FIFO_ALMOST_FULL_BIT) { while (radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT > 0) { DPRINT("RX FIFO: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); /* Read out the FIFO Count bytes of RX FIFO */ ezradio_read_rx_fifo(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT, &(rx_packet->data[rx_fifo_data_lenght])); rx_fifo_data_lenght += radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT; //DPRINT("%d of %d bytes collected", rx_fifo_data_lenght, rx_packet->data[0]+1); ezradio_fifo_info(0, &radioReplyLocal); if (rx_fifo_data_lenght >= expected_data_length) { ezradio_handle_end_of_packet(); return; } } ezradio_int_callback(); return; } } } else if (ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_CRC_ERROR_BIT) //} else if ( ezradioReply.FRR_A_READ.FRR_B_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_CRC_ERROR_BIT) { DPRINT("- PACKET_RX CRC_ERROR IRQ"); /* Check how many bytes we received. */ ezradio_fifo_info(0, &radioReplyLocal); DPRINT("RX ISR packetLength: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); //ezradio_cmd_reply_t radioReplyLocal2; //ezradio_get_packet_info(0, 0, 0, &radioReplyLocal2); if (rx_fifo_data_lenght == 0) { rx_packet = alloc_packet_callback(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); } /* Read out the RX FIFO content. */ ezradio_read_rx_fifo(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT, &(rx_packet->data[rx_fifo_data_lenght])); rx_packet->rx_meta.crc_status = HW_CRC_INVALID; rx_packet->length = rx_packet->data[0] + 1; DPRINT_DATA(rx_packet->data, rx_packet->length); DEBUG_RX_END(); if(rx_packet_callback != NULL) rx_packet_callback(rx_packet); else release_packet_callback(rx_packet); if(current_state == HW_RADIO_STATE_RX) { start_rx(¤t_rx_cfg); } } else { DPRINT((" - OTHER RX IRQ")); } break; case HW_RADIO_STATE_TX: if (ezradioReply.GET_INT_STATUS.PH_PEND & EZRADIO_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT) //if (ezradioReply.FRR_A_READ.FRR_C_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT) { DPRINT("PACKET_SENT IRQ"); DEBUG_TX_END(); if(tx_packet_callback != 0) { current_packet->tx_meta.timestamp = timer_get_counter_value(); DPRINT_DATA(current_packet->data, current_packet->length); tx_packet_callback(current_packet); } /* We can't switch back to Rx since the Rx callbacks are modified * during CCA, so we systematically go to idle */ switch_to_idle_mode(); // } else if (ezradioReply.FRR_A_READ.FRR_C_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_PEND_TX_FIFO_ALMOST_EMPTY_PEND_BIT) // { // DPRINT(" - TX FIFO Almost empty IRQ "); // // ezradio_fifo_info(0, &radioReplyLocal); // DPRINT("TX FIFO Space: %d", radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE); // // //Fill fifo // #ifdef HAL_RADIO_USE_HW_CRC // int16_t new_length = current_packet->length-1 - tx_fifo_data_length; // #else // int16_t new_length = current_packet->length+1 - tx_fifo_data_length; // #endif // if (new_length > radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE) new_length = radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE; // // while (new_length > 0) // { // ezradio_write_tx_fifo(new_length, &(current_packet->data[tx_fifo_data_length])); // tx_fifo_data_length += new_length; // DPRINT ("%d added -> %d", new_length, tx_fifo_data_length); // // #ifdef HAL_RADIO_USE_HW_CRC // new_length = current_packet->length-1 - tx_fifo_data_length; // #else // new_length = current_packet->length+1 - tx_fifo_data_length; // #endif // if (new_length > radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE) new_length = radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE; // } // // if (new_length == 0) // { // DPRINT("reprocess callback"); // ezradio_int_callback(); // return; // } // // DPRINT ("%d added -> %d", new_length, tx_fifo_data_length); } else { DPRINT(" - OTHER IRQ"); } break; default: //assert(false); DPRINT("State: %d", current_state); } } // if (ezradioReply.FRR_A_READ.FRR_A_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_MODEM_INT_PEND_BIT) // { // DPRINT("MODEM ISR"); // } // if (ezradioReply.FRR_A_READ.FRR_A_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_CHIP_INT_PEND_BIT) // { // DPRINT("CHIP ISR"); // // if (current_state != HW_RADIO_STATE_IDLE) // { // if (ezradioReply.GET_INT_STATUS.CHIP_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_CHIP_STATUS_STATE_CHANGE_BIT) // { // ezradio_request_device_state(&radioReplyLocal); // DPRINT(" - Current State %d", radioReplyLocal.REQUEST_DEVICE_STATE.CURR_STATE); // DPRINT(" - Current channel %d", radioReplyLocal.REQUEST_DEVICE_STATE.CURRENT_CHANNEL); // }else { // DPRINT(" - OTHER IRQ"); // } // } // } }
static void execute_csma_ca() { // TODO generate random channel queue //hw_radio_set_rx(NULL, NULL, NULL); // put radio in RX but disable callbacks to make sure we don't receive packets when in this state // TODO use correct rx cfg + it might be interesting to switch to idle first depending on calculated offset uint16_t tx_duration = calculate_tx_duration(); timer_tick_t Tc = CONVERT_TO_TI(current_packet->d7atp_tc); switch (dll_state) { case DLL_STATE_CSMA_CA_STARTED: { dll_tca = Tc - tx_duration; dll_cca_started = timer_get_counter_value(); DPRINT("Tca= %i = %i - %i", dll_tca, Tc, tx_duration); #ifndef FRAMEWORK_TIMER_RESET_COUNTER // Adjust TCA value according the time already elapsed in the response period if (tc_starting_time) // TODO how do manage tc_starting_time? not set for now { dll_tca -= dll_cca_started - tc_starting_time; DPRINT("Adjusted Tca= %i = %i - %i", dll_tca, dll_cca_started, tc_starting_time); } #endif if (dll_tca <= 0) { DPRINT("Tca negative, CCA failed"); // Let the upper layer decide eventually to change the channel in order to get a chance a send this frame switch_state(DLL_STATE_IDLE); d7anp_signal_packet_csma_ca_insertion_completed(false); break; } uint16_t t_offset = 0; csma_ca_mode_t csma_ca_mode = current_access_profile->control_csma_ca_mode; // TODO overrule mode to UNC for subsequent requests by the requester, or a single response to a unicast request switch(csma_ca_mode) { case CSMA_CA_MODE_UNC: // no delay dll_slot_duration = 0; break; case CSMA_CA_MODE_AIND: // TODO implement AIND { dll_slot_duration = tx_duration; // no initial delay break; } case CSMA_CA_MODE_RAIND: // TODO implement RAIND { dll_slot_duration = tx_duration; uint16_t max_nr_slots = dll_tca / tx_duration; uint16_t slots_wait = get_rnd() % max_nr_slots; t_offset = slots_wait * tx_duration; break; } case CSMA_CA_MODE_RIGD: // TODO implement RAIND { dll_rigd_n = 0; dll_tca0 = dll_tca; dll_slot_duration = (uint16_t) ((double)dll_tca0) / (2 << (dll_rigd_n)); t_offset = get_rnd() % dll_slot_duration; break; } } DPRINT("slot duration: %i t_offset: %i csma ca mode: %i", dll_slot_duration, t_offset, csma_ca_mode); dll_to = dll_tca - t_offset; if (t_offset > 0) { switch_state(DLL_STATE_CCA1); timer_post_task_delay(&execute_cca, t_offset); } else { switch_state(DLL_STATE_CCA1); sched_post_task(&execute_cca); } break; } case DLL_STATE_CSMA_CA_RETRY: { int32_t cca_duration = timer_get_counter_value() - dll_cca_started; dll_to -= cca_duration; DPRINT("RETRY dll_to = %i < %i ", dll_to, t_g); if (dll_to < t_g) { switch_state(DLL_STATE_CCA_FAIL); sched_post_task(&execute_csma_ca); break; } dll_tca = dll_to; dll_cca_started = timer_get_counter_value(); uint16_t t_offset = 0; switch(current_access_profile->control_csma_ca_mode) { case CSMA_CA_MODE_AIND: case CSMA_CA_MODE_RAIND: { uint16_t max_nr_slots = dll_tca / tx_duration; uint16_t slots_wait = get_rnd() % max_nr_slots; t_offset = slots_wait * tx_duration; break; } case CSMA_CA_MODE_RIGD: { dll_rigd_n++; dll_slot_duration = (uint16_t) ((double)dll_tca0) / (2 << (dll_rigd_n+1)); if(dll_slot_duration != 0) // TODO can be 0, validate t_offset = get_rnd() % dll_slot_duration; else t_offset = 0; DPRINT("slot duration: %i", dll_slot_duration); break; } } DPRINT("t_offset: %i", t_offset); dll_to = dll_tca - t_offset; if (t_offset > 0) { timer_post_task_delay(&execute_csma_ca, t_offset); } else { switch_state(DLL_STATE_CCA1); sched_post_task(&execute_cca); } break; } case DLL_STATE_CCA_FAIL: { // TODO hw_radio_set_idle(); switch_state(DLL_STATE_IDLE); d7anp_signal_packet_csma_ca_insertion_completed(false); if (process_received_packets_after_tx) { sched_post_task(&process_received_packets); process_received_packets_after_tx = false; } if (resume_fg_scan) { switch_state(DLL_STATE_FOREGROUND_SCAN); hw_rx_cfg_t rx_cfg = (hw_rx_cfg_t){ .channel_id.channel_header = current_access_profile->subbands[0].channel_header, .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start, .syncword_class = PHY_SYNCWORD_CLASS1, }; hw_radio_set_rx(&rx_cfg, &packet_received, NULL); resume_fg_scan = false; } break; } } } void dll_execute_scan_automation() { uint8_t scan_access_class = fs_read_dll_conf_active_access_class(); if(active_access_class != scan_access_class) { fs_read_access_class(scan_access_class, &scan_access_profile); active_access_class = scan_access_class; } current_access_profile = &scan_access_profile; if(current_access_profile->control_scan_type_is_foreground && current_access_profile->control_number_of_subbands > 0) // TODO background scan { assert(current_access_profile->control_number_of_subbands == 1); // TODO multiple not supported switch_state(DLL_STATE_SCAN_AUTOMATION); hw_rx_cfg_t rx_cfg = { .channel_id = { .channel_header = current_access_profile->subbands[0].channel_header, .center_freq_index = current_access_profile->subbands[0].channel_index_start }, .syncword_class = PHY_SYNCWORD_CLASS1 };
static uint64_t esp_apptrace_test_ts_get() { uint64_t ts = 0; timer_get_counter_value(s_ts_timer_group, s_ts_timer_idx, &ts); return ts; }
static void end_of_packet_isr() { cc1101_interface_set_interrupts_enabled(false); DPRINT("end of packet ISR"); switch(current_state) { case HW_RADIO_STATE_RX: ; uint8_t packet_len = cc1101_interface_read_single_reg(RXFIFO); DPRINT("EOP ISR packetLength: %d", packet_len); if(packet_len >= 63) { // long packets not yet supported or bit error in length byte, don't assert but flush rx DPRINT("Packet size too big, flushing RX"); uint8_t status = (cc1101_interface_strobe(RF_SNOP) & 0xF0); if(status == 0x60) { // RX overflow cc1101_interface_strobe(RF_SFRX); } else if(status == 0x10) { // still in RX, switch to idle first cc1101_interface_strobe(RF_SIDLE); } while(cc1101_interface_strobe(RF_SNOP) != 0x0F); // wait until in idle state cc1101_interface_strobe(RF_SRX); while(cc1101_interface_strobe(RF_SNOP) != 0x1F); // wait until in RX state cc1101_interface_set_interrupts_enabled(true); return; } hw_radio_packet_t* packet = alloc_packet_callback(packet_len); packet->length = packet_len; cc1101_interface_read_burst_reg(RXFIFO, packet->data + 1, packet->length); // fill rx_meta packet->rx_meta.rssi = convert_rssi(cc1101_interface_read_single_reg(RXFIFO)); packet->rx_meta.lqi = cc1101_interface_read_single_reg(RXFIFO) & 0x7F; memcpy(&(packet->rx_meta.rx_cfg.channel_id), ¤t_channel_id, sizeof(channel_id_t)); packet->rx_meta.crc_status = HW_CRC_UNAVAILABLE; // TODO packet->rx_meta.timestamp = timer_get_counter_value(); #ifdef FRAMEWORK_LOG_ENABLED log_print_raw_phy_packet(packet, false); #endif rx_packet_callback(packet); if(current_state == HW_RADIO_STATE_RX) // check still in RX, could be modified by upper layer while in callback { uint8_t status = (cc1101_interface_strobe(RF_SNOP) & 0xF0); if(status == 0x60) // RX overflow { cc1101_interface_strobe(RF_SFRX); while(cc1101_interface_strobe(RF_SNOP) != 0x0F); // wait until in idle state cc1101_interface_strobe(RF_SRX); while(cc1101_interface_strobe(RF_SNOP) != 0x1F); // wait until in RX state } cc1101_interface_set_interrupts_enabled(true); assert(cc1101_interface_strobe(RF_SNOP) == 0x1F); // expect to be in RX mode } break; case HW_RADIO_STATE_TX: if(!should_rx_after_tx_completed) switch_to_idle_mode(); current_packet->tx_meta.timestamp = timer_get_counter_value(); #ifdef FRAMEWORK_LOG_ENABLED log_print_raw_phy_packet(current_packet, true); #endif if(tx_packet_callback != 0) tx_packet_callback(current_packet); if(should_rx_after_tx_completed) { // RX requested while still in TX ... // TODO this could probably be further optimized by not going into IDLE // after RX by setting TXOFF_MODE to RX (if the cfg is the same at least) should_rx_after_tx_completed = false; start_rx(&pending_rx_cfg); } break; default: assert(false); } }
static void ezradio_int_callback() { //DPRINT("ezradio ISR"); ezradio_cmd_reply_t ezradioReply; ezradio_cmd_reply_t radioReplyLocal; ezradio_get_int_status(0x0, 0x0, 0x0, &ezradioReply); //ezradio_frr_a_read(3, &ezradioReply); //DPRINT(" - INT_PEND %s", byte_to_binary(ezradioReply.FRR_A_READ.FRR_A_VALUE)); // DPRINT(" - INT_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.INT_PEND)); // DPRINT(" - INT_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.INT_STATUS)); // DPRINT(" - PH_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.PH_PEND)); //DPRINT(" - PH_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.PH_STATUS)); //DPRINT(" - PH_STATUS %s", byte_to_binary(ezradioReply.FRR_A_READ.FRR_B_VALUE)); // DPRINT(" - MODEM_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.MODEM_PEND)); // DPRINT(" - MODEM_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.MODEM_STATUS)); // DPRINT(" - CHIP_PEND %s", byte_to_binary(ezradioReply.GET_INT_STATUS.CHIP_PEND)); // DPRINT(" - CHIP_STATUS %s", byte_to_binary(ezradioReply.GET_INT_STATUS.CHIP_STATUS)); //if (ezradioReply.FRR_A_READ.FRR_A_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_PH_INT_PEND_BIT) if (ezradioReply.GET_INT_STATUS.INT_PEND & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_PH_INT_PEND_BIT) { //DPRINT("PH ISR"); switch(current_state) { case HW_RADIO_STATE_RX: if (ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_PACKET_RX_BIT) //if (ezradioReply.FRR_A_READ.FRR_B_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_PACKET_RX_BIT) { DPRINT("PACKET_RX IRQ"); if(rx_packet_callback != NULL) { /* Check how many bytes we received. */ ezradio_fifo_info(0, &radioReplyLocal); DPRINT("RX ISR packetLength: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); //ezradio_cmd_reply_t radioReplyLocal2; //ezradio_get_packet_info(0, 0, 0, &radioReplyLocal2); if (rx_fifo_data_lenght == 0) { rx_packet = alloc_packet_callback(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); } // hw_radio_packet_t* packet = alloc_packet_callback(radioReplyLocal2.PACKET_INFO.LENGTH); // packet->length = radioReplyLocal2.PACKET_INFO.LENGTH; /* Read out the RX FIFO content. */ ezradio_read_rx_fifo(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT, &(rx_packet->data[rx_fifo_data_lenght])); //ezradio_read_rx_fifo(radioReplyLocal2.PACKET_INFO.LENGTH, packet->data); ezradio_handle_end_of_packet(); } } else if (ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_RX_FIFO_ALMOST_FULL_BIT) //} else if (ezradioReply.FRR_A_READ.FRR_B_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_RX_FIFO_ALMOST_FULL_BIT) { //DPRINT("- RX FIFO almost full IRQ"); ezradio_fifo_info(0, &radioReplyLocal); if (rx_fifo_data_lenght == 0) { DPRINT("RX FIFO: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); uint8_t buffer[4]; ezradio_read_rx_fifo(4, buffer); uint8_t length = buffer[0]; if (current_rx_cfg.channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { uint8_t fec_buffer[4]; memcpy(fec_buffer, buffer, 4); fec_decode_packet(fec_buffer, 4, 4); length = fec_calculated_decoded_length(fec_buffer[0]+1); DPRINT("RX Packet Length: %d / %d", fec_buffer[0], length); } rx_packet = alloc_packet_callback(length+1); rx_packet->length = length; memcpy(rx_packet->data, buffer, 4); rx_fifo_data_lenght += 4; radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT-=4; } while (radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT > 0) { DPRINT("RX FIFO: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); /* Read out the FIFO Count bytes of RX FIFO */ ezradio_read_rx_fifo(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT, &(rx_packet->data[rx_fifo_data_lenght])); rx_fifo_data_lenght += radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT; //DPRINT("%d of %d bytes collected", rx_fifo_data_lenght, rx_packet->data[0]+1); ezradio_fifo_info(0, &radioReplyLocal); if (rx_fifo_data_lenght >= rx_packet->length + 1) { ezradio_handle_end_of_packet(); return; } } ezradio_int_callback(); return; } else if (ezradioReply.GET_INT_STATUS.PH_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_CRC_ERROR_BIT) //} else if ( ezradioReply.FRR_A_READ.FRR_B_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_STATUS_CRC_ERROR_BIT) { DPRINT("- PACKET_RX CRC_ERROR IRQ"); /* Check how many bytes we received. */ ezradio_fifo_info(0, &radioReplyLocal); DPRINT("RX ISR packetLength: %d", radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); //ezradio_cmd_reply_t radioReplyLocal2; //ezradio_get_packet_info(0, 0, 0, &radioReplyLocal2); if (rx_fifo_data_lenght == 0) { rx_packet = alloc_packet_callback(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT); } /* Read out the RX FIFO content. */ ezradio_read_rx_fifo(radioReplyLocal.FIFO_INFO.RX_FIFO_COUNT, &(rx_packet->data[rx_fifo_data_lenght])); rx_packet->rx_meta.crc_status = HW_CRC_INVALID; rx_packet->length = rx_packet->data[0] + 1; DPRINT_PACKET(rx_packet, false); DEBUG_RX_END(); if(rx_packet_callback != NULL) rx_packet_callback(rx_packet); else release_packet_callback(rx_packet); if(current_state == HW_RADIO_STATE_RX) { start_rx(¤t_rx_cfg); } } else { DPRINT((" - OTHER RX IRQ")); } break; case HW_RADIO_STATE_TX: if (ezradioReply.GET_INT_STATUS.PH_PEND & EZRADIO_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT) //if (ezradioReply.FRR_A_READ.FRR_C_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT) { DPRINT("PACKET_SENT IRQ"); DEBUG_TX_END(); if(!should_rx_after_tx_completed) switch_to_idle_mode(); current_packet->tx_meta.timestamp = timer_get_counter_value(); DPRINT_PACKET(current_packet, true); if(tx_packet_callback != 0) tx_packet_callback(current_packet); if(should_rx_after_tx_completed) { // RX requested while still in TX ... // TODO this could probably be further optimized by not going into IDLE // after RX by setting TXOFF_MODE to RX (if the cfg is the same at least) should_rx_after_tx_completed = false; start_rx(¤t_rx_cfg); } // } else if (ezradioReply.FRR_A_READ.FRR_C_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_PH_PEND_TX_FIFO_ALMOST_EMPTY_PEND_BIT) // { // DPRINT(" - TX FIFO Almost empty IRQ "); // // ezradio_fifo_info(0, &radioReplyLocal); // DPRINT("TX FIFO Space: %d", radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE); // // //Fill fifo // #ifdef HAL_RADIO_USE_HW_CRC // int16_t new_length = current_packet->length-1 - tx_fifo_data_length; // #else // int16_t new_length = current_packet->length+1 - tx_fifo_data_length; // #endif // if (new_length > radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE) new_length = radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE; // // while (new_length > 0) // { // ezradio_write_tx_fifo(new_length, &(current_packet->data[tx_fifo_data_length])); // tx_fifo_data_length += new_length; // DPRINT ("%d added -> %d", new_length, tx_fifo_data_length); // // #ifdef HAL_RADIO_USE_HW_CRC // new_length = current_packet->length-1 - tx_fifo_data_length; // #else // new_length = current_packet->length+1 - tx_fifo_data_length; // #endif // if (new_length > radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE) new_length = radioReplyLocal.FIFO_INFO.TX_FIFO_SPACE; // } // // if (new_length == 0) // { // DPRINT("reprocess callback"); // ezradio_int_callback(); // return; // } // // DPRINT ("%d added -> %d", new_length, tx_fifo_data_length); } else { DPRINT(" - OTHER IRQ"); } break; default: //assert(false); DPRINT("State: %d", current_state); } } // if (ezradioReply.FRR_A_READ.FRR_A_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_MODEM_INT_PEND_BIT) // { // DPRINT("MODEM ISR"); // } // if (ezradioReply.FRR_A_READ.FRR_A_VALUE & EZRADIO_CMD_GET_INT_STATUS_REP_INT_PEND_CHIP_INT_PEND_BIT) // { // DPRINT("CHIP ISR"); // // if (current_state != HW_RADIO_STATE_IDLE) // { // if (ezradioReply.GET_INT_STATUS.CHIP_STATUS & EZRADIO_CMD_GET_INT_STATUS_REP_CHIP_STATUS_STATE_CHANGE_BIT) // { // ezradio_request_device_state(&radioReplyLocal); // DPRINT(" - Current State %d", radioReplyLocal.REQUEST_DEVICE_STATE.CURR_STATE); // DPRINT(" - Current channel %d", radioReplyLocal.REQUEST_DEVICE_STATE.CURRENT_CHANNEL); // }else { // DPRINT(" - OTHER IRQ"); // } // } // } }
static void rssi_valid(int16_t rssi) { log_print_string("Rssi valid at time %u", timer_get_counter_value()); }