Exemplo n.º 1
0
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;
    }
}
Exemplo n.º 2
0
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(&current_rx_cfg, rx_cfg, sizeof(hw_rx_cfg_t));
	}
	else
	{
		start_rx(&current_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);
}
Exemplo n.º 6
0
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);
    }
}
Exemplo n.º 7
0
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), &current_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*)&current_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(&current_rx_cfg);
	}
}
Exemplo n.º 10
0
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(&current_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");
//			}
//		}
//	}


}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
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), &current_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);
    }
}
Exemplo n.º 14
0
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(&current_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(&current_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");
//			}
//		}
//	}


}