コード例 #1
0
ファイル: cflie_nrf24l01.c プロジェクト: F-D-R/deviation
MODULE_CALLTYPE
static u16 cflie_callback()
{
    switch (phase) {
    case CFLIE_INIT_SEARCH:
        send_search_packet();
        phase = CFLIE_SEARCH;
        break;
    case CFLIE_INIT_CRTP_LOG:
        if (crtp_log_setup_state_machine()) {
            phase = CFLIE_INIT_DATA;
        }
        break;
    case CFLIE_INIT_DATA:
        send_cmd_packet();
        phase = CFLIE_DATA;
        break;
    case CFLIE_SEARCH:
        switch (packet_ack()) {
        case PKT_PENDING:
            return PACKET_CHKTIME;                 // packet send not yet complete
        case PKT_ACKED:
            phase = CFLIE_DATA;
            PROTOCOL_SetBindState(0);
            MUSIC_Play(MUSIC_DONE_BINDING);
            break;
        case PKT_TIMEOUT:
            send_search_packet();
            counter = BIND_COUNT;
        }
        break;

    case CFLIE_DATA:
        if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_CRTPLOG) {
            update_telemetry_crtplog();
        } else if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_ACKPKT) {
            update_telemetry_ackpkt();
        }

        if (packet_ack() == PKT_PENDING)
            return PACKET_CHKTIME;         // packet send not yet complete
        send_cmd_packet();
        break;
    }
    return PACKET_PERIOD;                  // Packet at standard protocol interval
}
コード例 #2
0
ファイル: cflie_nrf24l01.c プロジェクト: phantom-8/deviation
MODULE_CALLTYPE
static u16 cflie_callback()
{
    switch (phase) {
    case CFLIE_INIT_SEARCH:
        send_search_packet();
        phase = CFLIE_SEARCH;
        break;
    case CFLIE_INIT_TELEMETRY:
        if (telemetry_setup_state_machine()) {
            phase = CFLIE_INIT_DATA;
        }
        break;
    case CFLIE_INIT_DATA:
        send_cmd_packet();
        phase = CFLIE_DATA;
        break;
    case CFLIE_SEARCH:
        switch (packet_ack()) {
        case PKT_PENDING:
            return PACKET_CHKTIME;                 // packet send not yet complete
        case PKT_ACKED:
            phase = CFLIE_DATA;
            PROTOCOL_SetBindState(0);
            MUSIC_Play(MUSIC_DONE_BINDING);
            break;
        case PKT_TIMEOUT:
            send_search_packet();
            counter = BIND_COUNT;
        }
        break;

    case CFLIE_DATA:
        update_telemetry();
        if (packet_ack() == PKT_PENDING)
            return PACKET_CHKTIME;         // packet send not yet complete
        send_cmd_packet();
        break;
    }
    return PACKET_PERIOD;                  // Packet at standard protocol interval
}
コード例 #3
0
ファイル: hardware.c プロジェクト: mogchen/Homura-Note
int hw_start(struct net_adapter *adapter)
{
	struct wimax_cfg *g_cfg = adapter->pdata->g_cfg;

	if (load_wimax_image(g_cfg->wimax_mode))
		return STATUS_UNSUCCESSFUL;

	adapter->download_complete = FALSE;

	if (adapter->downloading) {
		sdio_claim_host(adapter->func);
		send_cmd_packet(adapter, MSG_DRIVER_OK_REQ);
		sdio_release_host(adapter->func);
		switch (wait_event_interruptible_timeout
				(adapter->download_event,
				(adapter->download_complete == TRUE),
				msecs_to_jiffies(FWDOWNLOAD_TIMEOUT))) {
		case 0:
			/* timeout */
			dump_debug("Error hw_start :"
				"F/W Download timeout failed");
			adapter->halted = TRUE;
			return STATUS_UNSUCCESSFUL;
		case -ERESTARTSYS:
			/* Interrupted by signal */
			dump_debug("Error hw_start :  -ERESTARTSYS retry");
			return STATUS_UNSUCCESSFUL;
		default:
			/* normal condition check */
			if (adapter->removed == TRUE
				|| adapter->halted == TRUE) {
				dump_debug("Error hw_start : "
					" F/W Download surprise removed");
				return STATUS_UNSUCCESSFUL;
			}

			/*Setup hostwake interrupt*/

			if (cmc732_setup_wake_irq(adapter) < 0)
				dump_debug("hw_start : "
					" Error setting up wimax_int");


			break;
		}
		adapter->downloading = FALSE;
	}

	return STATUS_SUCCESS;
}
コード例 #4
0
int wimax_hw_start(struct net_adapter *adapter)
{
	struct wimax732_platform_data *pdata = adapter->pdata;

	pdata->g_cfg->wimax_status = WIMAX_STATE_READY;
	adapter->download_complete = false;

	adapter->rx_task = kthread_create(
					cmc732_receive_thread,	adapter, "%s",
					"cmc732_receive_thread");

	adapter->tx_task = kthread_create(
					cmc732_send_thread,	adapter, "%s",
					"cmc732_send_thread");

	init_waitqueue_head(&adapter->receive_event);
	init_waitqueue_head(&adapter->send_event);

	if (adapter->rx_task && adapter->tx_task) {
		wake_up_process(adapter->rx_task);
		wake_up_process(adapter->tx_task);
	} else {
		pr_debug("Unable to create send-receive threads");
		return STATUS_UNSUCCESSFUL;
	}

	if (load_wimax_image(pdata->g_cfg->wimax_mode, adapter))
		return STATUS_UNSUCCESSFUL;

	if (adapter->downloading) {

		send_cmd_packet(adapter, MSG_DRIVER_OK_REQ);

		switch (wait_event_interruptible_timeout(
				adapter->download_event,
				(adapter->download_complete),
				HZ*FWDOWNLOAD_TIMEOUT)) {
		case 0:
			/* timeout */
			pr_debug("Error wimax_hw_start : \
					F/W Download timeout failed");
			goto download_fail;
		case -ERESTARTSYS:
			/* Interrupted by signal */
			pr_debug("Error wimax_hw_start :"
					"-ERESTARTSYS retry");
			goto download_fail;
		default:
			/* normal condition check */
			if (adapter->removed || adapter->halted) {
				pr_debug("Error wimax_hw_start :	\
						F/W Download surprise removed");
				goto download_fail;
			}
			pr_debug("wimax_hw_start :  F/W Download Complete");
			unload_wimax_image(adapter);

			if (cmc732_setup_wake_irq(adapter) < 0)
				pr_debug("wimax_hw_start :"
						"Error setting up wimax_int");

			break;
		}
コード例 #5
0
static void process_indicate_packet(struct net_adapter *adapter, u8 *buffer)
{
	struct wimax_msg_header *packet;
	struct wimax_cfg *g_cfg = adapter->pdata->g_cfg;
	char *tmp_byte;

	packet = (struct wimax_msg_header *)buffer;

	if (packet->type != be16_to_cpu(ETHERTYPE_DL)) {
		pr_warn("%s: not a download packet\n", __func__);
		return;
	}

	switch (be16_to_cpu(packet->id)) {
	case MSG_DRIVER_OK_RESP:
		pr_debug("%s: MSG_DRIVER_OK_RESP\n", __func__);
		send_image_info_packet(adapter, MSG_IMAGE_INFO_REQ);
		break;
	case MSG_IMAGE_INFO_RESP:
		pr_debug("%s: MSG_IMAGE_INFO_RESP\n", __func__);
		send_image_data_packet(adapter, MSG_IMAGE_DATA_REQ);
		break;
	case MSG_IMAGE_DATA_RESP:
		if (adapter->wimax_image.offset == adapter->wimax_image.size) {
			pr_debug("%s: Image Download Complete\n", __func__);
			send_cmd_packet(adapter, MSG_RUN_REQ);
		} else {
			send_image_data_packet(adapter, MSG_IMAGE_DATA_REQ);
		}
		break;
	case MSG_RUN_RESP:
		tmp_byte = (char *)(buffer + sizeof(struct wimax_msg_header));

		if (*tmp_byte != 0x01)
			break;

		adapter->download_complete = true;
		wake_up_interruptible(&adapter->download_event);

		pr_debug("%s: MSG_RUN_RESP\n", __func__);
		if (g_cfg->wimax_mode == SDIO_MODE
			|| g_cfg->wimax_mode == DM_MODE
			|| g_cfg->wimax_mode == USB_MODE
			|| g_cfg->wimax_mode	== USIM_RELAY_MODE) {

			adapter->mac_task = kthread_create(
					wimax_hw_get_mac_address, adapter,
					"%s", "mac_request_thread");
			if (adapter->mac_task)
				wake_up_process(adapter->mac_task);

		} else if (g_cfg->wimax_mode == WTM_MODE
				|| g_cfg->wimax_mode == AUTH_MODE) {
			adapter->download_complete = true;
			wake_up_interruptible(&adapter->download_event);
		}
		break;
	default:
		pr_err("%s: Unknown packet type\n", __func__);
		break;
	}
}
コード例 #6
0
ファイル: cflie_nrf24l01.c プロジェクト: phantom-8/deviation
// State machine for setting up telemetry
// returns 1 when the state machine has completed, 0 otherwise
static u8 telemetry_setup_state_machine()
{
    u8 state_machine_completed = 0;
    // A note on the design of this state machine:
    //
    // Responses from the crazyflie come in the form of ACK payloads.
    // There is no retry logic associated with ACK payloads, so it is possible
    // to miss a response from the crazyflie. To avoid this, the request
    // packet must be re-sent until the expected response is received. However,
    // re-sending the same request generates another response in the crazyflie
    // Rx queue, which can produce large backlogs of duplicate responses.
    //
    // To avoid this backlog but still guard against dropped ACK payloads,
    // transmit cmd packets (which don't generate responses themselves)
    // until an empty ACK payload is received (the crazyflie alternates between
    // 0xF3 and 0xF7 for empty ACK payloads) which indicates the Rx queue on the
    // crazyflie has been drained. If the queue has been drained and the
    // desired ACK has still not been received, it was likely dropped and the
    // request should be re-transmit.

    switch (telemetry_setup_state) {
    case CFLIE_TELEM_SETUP_STATE_INIT:
        toc_size = 0;
        next_toc_variable = 0;
        vbat_var_id = 0;
        extvbat_var_id = 0;
        telemetry_setup_state = CFLIE_TELEM_SETUP_STATE_SEND_CMD_GET_INFO;
        // fallthrough
    case CFLIE_TELEM_SETUP_STATE_SEND_CMD_GET_INFO:
        telemetry_setup_state = CFLIE_TELEM_SETUP_STATE_ACK_CMD_GET_INFO;
        tx_packet[0] = crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_TOC);
        tx_packet[1] = CRTP_LOG_TOC_CMD_INFO;
        tx_payload_len = 2;
        send_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_ACK_CMD_GET_INFO:
        if (packet_ack() == PKT_ACKED) {
            if (rx_payload_len >= 3
                    && rx_packet[0] == crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_TOC)
                    && rx_packet[1] == CRTP_LOG_TOC_CMD_INFO) {
                // Received the ACK payload. Save the toc_size
                // and advance to the next state
                toc_size = rx_packet[2];
                telemetry_setup_state =
                        CFLIE_TELEM_SETUP_STATE_SEND_CMD_GET_ITEM;
                return state_machine_completed;
            } else if (rx_packet[0] == 0xF3 || rx_packet[0] == 0xF7) {
                // "empty" ACK packet received - likely missed the ACK
                // payload we are waiting for.
                // return to the send state and retransmit the request
                telemetry_setup_state =
                        CFLIE_TELEM_SETUP_STATE_SEND_CMD_GET_INFO;
                return state_machine_completed;
            }
        }

        // Otherwise, send a cmd packet to get the next ACK in the Rx queue
        send_cmd_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_SEND_CMD_GET_ITEM:
        telemetry_setup_state = CFLIE_TELEM_SETUP_STATE_ACK_CMD_GET_ITEM;
        tx_packet[0] = crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_TOC);
        tx_packet[1] = CRTP_LOG_TOC_CMD_ELEMENT;
        tx_packet[2] = next_toc_variable;
        tx_payload_len = 3;
        send_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_ACK_CMD_GET_ITEM:
        if (packet_ack() == PKT_ACKED) {
            if (rx_payload_len >= 3
                    && rx_packet[0] == crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_TOC)
                    && rx_packet[1] == CRTP_LOG_TOC_CMD_ELEMENT
                    && rx_packet[2] == next_toc_variable) {
                // For every element in the TOC we must compare its
                // type (rx_packet[3]), group and name (back to back
                // null terminated strings starting with the fifth byte)
                // and see if it matches any of the variables we need
                // for logging
                //
                // Currently enabled for logging:
                //  - vbatMV (LOG_UINT16)
                //  - extVbatMV (LOG_UINT16)
                if(rx_packet[3] == vbat_var_type
                        && (0 == strcmp((char*)&rx_packet[4], pm_group_name))
                        && (0 == strcmp((char*)&rx_packet[4 + strlen(pm_group_name) + 1], vbat_var_name))) {
                    // Found the vbat element - save it for later
                    vbat_var_id = next_toc_variable;
                }

                if(rx_packet[3] == extvbat_var_type
                        && (0 == strcmp((char*)&rx_packet[4], pm_group_name))
                        && (0 == strcmp((char*)&rx_packet[4 + strlen(pm_group_name) + 1], extvbat_var_name))) {
                    // Found the extvbat element - save it for later
                    extvbat_var_id = next_toc_variable;
                }

                // Advance the toc variable counter
                // If there are more variables, read them
                // If not, move on to the next state
                next_toc_variable += 1;
                if(next_toc_variable >= toc_size) {
                    telemetry_setup_state = CFLIE_TELEM_SETUP_STATE_SEND_CONTROL_CREATE_BLOCK;
                } else {
                    // There are more TOC elements to get
                    telemetry_setup_state = CFLIE_TELEM_SETUP_STATE_SEND_CMD_GET_ITEM;
                }
                return state_machine_completed;
            } else if (rx_packet[0] == 0xF3 || rx_packet[0] == 0xF7) {
                // "empty" ACK packet received - likely missed the ACK
                // payload we are waiting for.
                // return to the send state and retransmit the request
                telemetry_setup_state =
                        CFLIE_TELEM_SETUP_STATE_SEND_CMD_GET_INFO;
                return state_machine_completed;
            }
        }

        // Otherwise, send a cmd packet to get the next ACK in the Rx queue
        send_cmd_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_SEND_CONTROL_CREATE_BLOCK:
        telemetry_setup_state = CFLIE_TELEM_SETUP_STATE_ACK_CONTROL_CREATE_BLOCK;
        tx_packet[0] = crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_SETTINGS);
        tx_packet[1] = CRTP_LOG_SETTINGS_CMD_CREATE_BLOCK;
        tx_packet[2] = CFLIE_TELEM_LOG_BLOCK_ID; // Log block ID
        tx_packet[3] = vbat_var_type; // Variable type
        tx_packet[4] = vbat_var_id; // ID of the VBAT variable
        tx_packet[5] = extvbat_var_type; // Variable type
        tx_packet[6] = extvbat_var_id; // ID of the ExtVBat variable
        tx_payload_len = 7;
        send_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_ACK_CONTROL_CREATE_BLOCK:
        if (packet_ack() == PKT_ACKED) {
            if (rx_payload_len >= 2
                    && rx_packet[0] == crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_SETTINGS)
                    && rx_packet[1] == CRTP_LOG_SETTINGS_CMD_CREATE_BLOCK) {
                // Received the ACK payload. Advance to the next state
                telemetry_setup_state =
                        CFLIE_TELEM_SETUP_STATE_SEND_CONTROL_START_BLOCK;
                return state_machine_completed;
            } else if (rx_packet[0] == 0xF3 || rx_packet[0] == 0xF7) {
                // "empty" ACK packet received - likely missed the ACK
                // payload we are waiting for.
                // return to the send state and retransmit the request
                telemetry_setup_state =
                        CFLIE_TELEM_SETUP_STATE_SEND_CONTROL_CREATE_BLOCK;
                return state_machine_completed;
            }
        }

        // Otherwise, send a cmd packet to get the next ACK in the Rx queue
        send_cmd_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_SEND_CONTROL_START_BLOCK:
        telemetry_setup_state = CFLIE_TELEM_SETUP_STATE_ACK_CONTROL_START_BLOCK;
        tx_packet[0] = crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_SETTINGS);
        tx_packet[1] = CRTP_LOG_SETTINGS_CMD_START_LOGGING;
        tx_packet[2] = CFLIE_TELEM_LOG_BLOCK_ID; // Log block ID 1
        tx_packet[3] = CFLIE_TELEM_LOG_BLOCK_PERIOD_10MS; // Log frequency in 10ms units
        tx_payload_len = 4;
        send_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_ACK_CONTROL_START_BLOCK:
        if (packet_ack() == PKT_ACKED) {
            if (rx_payload_len >= 2
                    && rx_packet[0] == crtp_create_header(CRTP_PORT_LOG, CRTP_LOG_CHAN_SETTINGS)
                    && rx_packet[1] == CRTP_LOG_SETTINGS_CMD_START_LOGGING) {
                // Received the ACK payload. Advance to the next state
                telemetry_setup_state =
                        CFLIE_TELEM_SETUP_STATE_COMPLETE;
                return state_machine_completed;
            } else if (rx_packet[0] == 0xF3 || rx_packet[0] == 0xF7) {
                // "empty" ACK packet received - likely missed the ACK
                // payload we are waiting for.
                // return to the send state and retransmit the request
                telemetry_setup_state =
                        CFLIE_TELEM_SETUP_STATE_SEND_CONTROL_START_BLOCK;
                return state_machine_completed;
            }
        }

        // Otherwise, send a cmd packet to get the next ACK in the Rx queue
        send_cmd_packet();
        break;

    case CFLIE_TELEM_SETUP_STATE_COMPLETE:
        state_machine_completed = 1;
        return state_machine_completed;
        break;
    }

    return state_machine_completed;
}