void app_tftp(char *arg) { struct command_t *commands; struct note_t *note; struct pico_tftp_session *session; int is_server_enabled = 0; int filesize; family = IPV6_MODE ? PICO_PROTO_IPV6 : PICO_PROTO_IPV4; commands = parse_arguments(arg); while (commands) { if (toupper(commands->operation) != 'S') note = transfer_prepare(&session, commands->operation, commands->filename, &commands->server_address, family); switch (commands->operation) { case 'S': case 's': if (!is_server_enabled) { pico_tftp_listen(PICO_PROTO_IPV4, (commands->operation == 'S') ? tftp_listen_cb_opt : tftp_listen_cb); is_server_enabled = 1; } break; case 'T': filesize = get_filesize(commands->filename); if (filesize < 0) { fprintf(stderr, "TFTP: unable to read size of file %s\n", commands->filename); exit(3); } pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize); start_tx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_tx_opt, note); break; case 't': start_tx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_tx, note); break; case 'R': pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, 0); start_rx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_rx_opt, note); break; case 'r': start_rx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_rx, note); } commands = commands->next; } }
error_t hw_radio_set_rx(hw_rx_cfg_t const* rx_cfg, rx_packet_callback_t rx_cb, rssi_valid_callback_t rssi_valid_cb) { if(rx_cb != NULL) { assert(alloc_packet_callback != NULL); assert(release_packet_callback != NULL); } assert(rx_cb != NULL || rssi_valid_cb != NULL); // at least one callback should be valid // TODO error handling EINVAL, EOFF rx_packet_callback = rx_cb; rssi_valid_callback = rssi_valid_cb; // if we are currently transmitting wait until TX completed before entering RX // we return now and go into RX when TX is completed if(current_state == HW_RADIO_STATE_TX) { should_rx_after_tx_completed = true; memcpy(&pending_rx_cfg, rx_cfg, sizeof(hw_rx_cfg_t)); return SUCCESS; } start_rx(rx_cfg); return SUCCESS; }
error_t hw_radio_set_rx(hw_rx_cfg_t const* rx_cfg, rx_packet_callback_t rx_cb, rssi_valid_callback_t rssi_valid_cb) { DPRINT("hw_radio_set_rx rx_cb %p rssi_valid_cb %p", rx_cb, rssi_valid_cb); if(rx_cb != NULL) { assert(alloc_packet_callback != NULL); assert(release_packet_callback != NULL); } // assert(rx_cb != NULL || rssi_valid_cb != NULL); // at least one callback should be valid // TODO error handling EINVAL, EOFF rx_packet_callback = rx_cb; rssi_valid_callback = rssi_valid_cb; // if we are currently transmitting wait until TX completed before entering RX // we return now and go into RX when TX is completed if(current_state == HW_RADIO_STATE_TX) { should_rx_after_tx_completed = true; DPRINT("now in TX, go into RX after completion"); return SUCCESS; } if (rx_cfg != NULL) { DPRINT("RX ch header=0x%02x, ind=%i", rx_cfg->channel_id.channel_header_raw, rx_cfg->channel_id.center_freq_index); start_rx(rx_cfg); memcpy(¤t_rx_cfg, rx_cfg, sizeof(hw_rx_cfg_t)); } else { start_rx(¤t_rx_cfg); } return SUCCESS; }
static void uart_speed(void) { struct uart_regs *uart = uart_info.uart; uart->line_ctrl = LCR_Divisor_Latch; uart->fifo = (char)UART_115200; /* lower baud rate div */ uart->irqe = (char)(UART_115200>>8); /* upper baud rate div */ uart->line_ctrl = 0; uart->line_ctrl = LCR_8_Bit_Word_1; uart->iir = (FCR_Fifo_Enable | FCR_Rx_Fifo_Reset | FCR_Tx_Fifo_Reset ); /* fifo ctrl */ uart->irqe = IER_Rx_Holding_Reg; /* enable rx intr */ tx_start(uart, uart_info.use_ints); start_rx(); }
static void rs_start(struct tty_struct *tty) { unsigned long flags; struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data; if (serial_paranoia_check(info,tty->device, "rs_start")) return; save_flags(flags); cli(); tx_start(info->uart, info->use_ints); start_rx(); restore_flags(flags); }
void tftp_listen_cb(union pico_address *addr, uint16_t port, uint16_t opcode, char *filename, int32_t len) { struct note_t *note; struct pico_tftp_session *session; printf("TFTP listen callback (BASIC) from remote port %" PRIu16 ".\n", short_be(port)); if (opcode == PICO_TFTP_RRQ) { printf("Received TFTP get request for %s\n", filename); note = transfer_prepare(&session, 't', filename, addr, family); start_tx(session, filename, port, cb_tftp_tx, note); } else if (opcode == PICO_TFTP_WRQ) { printf("Received TFTP put request for %s\n", filename); note = transfer_prepare(&session, 'r', filename, addr, family); start_rx(session, filename, port, cb_tftp_rx, note); } }
void tftp_listen_cb_opt(union pico_address *addr, uint16_t port, uint16_t opcode, char *filename, int32_t len) { struct note_t *note; struct pico_tftp_session *session; int options; uint8_t timeout; int32_t filesize; int ret; printf("TFTP listen callback (OPTIONS) from remote port %" PRIu16 ".\n", short_be(port)); /* declare the options we want to support */ ret = pico_tftp_parse_request_args(filename, len, &options, &timeout, &filesize); if (ret) pico_tftp_reject_request(addr, port, TFTP_ERR_EOPT, "Malformed request"); if (opcode == PICO_TFTP_RRQ) { printf("Received TFTP get request for %s\n", filename); note = transfer_prepare(&session, 'T', filename, addr, family); if (options & PICO_TFTP_OPTION_TIME) pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout); if (options & PICO_TFTP_OPTION_FILE) { ret = get_filesize(filename); if (ret < 0) { pico_tftp_reject_request(addr, port, TFTP_ERR_ENOENT, "File not found"); return; } pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, ret); } start_tx(session, filename, port, cb_tftp_tx_opt, note); } else { /* opcode == PICO_TFTP_WRQ */ printf("Received TFTP put request for %s\n", filename); note = transfer_prepare(&session, 'R', filename, addr, family); if (options & PICO_TFTP_OPTION_TIME) pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout); if (options & PICO_TFTP_OPTION_FILE) pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize); start_rx(session, filename, port, cb_tftp_rx_opt, note); } }
/* * This routine is called to set the UART divisor registers to match * the specified baud rate for a serial port. */ static void change_speed(struct cnxt_serial *info) { unsigned cflag; int i; if (!info->tty || !info->tty->termios) return; cflag = info->tty->termios->c_cflag; /* set the baudrate */ i = cflag & CBAUD; info->baud = baud_table[i]; uart_speed(); start_rx(); tx_start(info->uart, info->use_ints); return; }
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); } }
int main(void) { // Initialize the OSS-7 Stack system_init(); // Currently we address the Transport Layer for RX, this should go to an upper layer once it is working. trans_init(); trans_set_query_rx_callback(&rx_callback); trans_set_tx_callback(&tx_callback); // The initial Tca for the CSMA-CA in trans_set_initial_t_ca(200); start_channel_scan = true; log_print_string("gateway started"); // Log the device id log_print_data(device_id, 8); // configure blinking led event dim_led_event.next_event = 50; dim_led_event.f = &dim_led; system_watchdog_init(WDTSSEL0, 0x03); system_watchdog_timer_start(); blink_led(); while(1) { if (start_channel_scan) { start_rx(); } // Don't know why but system reboots when LPM > 1 since ACLK is uses for UART system_lowpower_mode(0,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"); // } // } // } }
int main(void) { system_init(); rtc_init_counter_mode(); rtc_start(); //test_fec_encoding(); //test_fec_decoding(); button_enable_interrupts(); phy_init(); phy_set_rx_callback(rx_callback); while(1) { if (INTERRUPT_BUTTON1 & interrupt_flags) { interrupt_flags &= ~INTERRUPT_BUTTON1; // led_toggle(1); start_tx(); button_clear_interrupt_flag(); button_enable_interrupts(); } if (INTERRUPT_BUTTON3 & interrupt_flags) { interrupt_flags &= ~INTERRUPT_BUTTON3; if (rtcEnabled) { rtcEnabled = 0; rtc_disable_interrupt(); } else { rtcEnabled = 1; rtc_enable_interrupt(); } button_clear_interrupt_flag(); button_enable_interrupts(); } if (INTERRUPT_RTC & interrupt_flags) { interrupt_flags &= ~INTERRUPT_RTC; led_toggle(0); start_tx(); } if (!phy_is_rx_in_progress() && !phy_is_tx_in_progress()) { start_rx(); } if (phy_is_rx_in_progress()) { led_on(2); } else { led_off(2); } if (phy_is_tx_in_progress()) { led_on(3); } else { led_off(3); } // system_lowpower_mode(4,1); } return 0; }
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"); // } // } // } }