コード例 #1
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Get Widget Parameters Reply (Label=3 \ref GET_WIDGET_PARAMS_REPLY)
 * The Widget sends this message to the PC in response to the Get Widget Parameters request.
 */
static void widget_get_params_reply(void) {
	struct _widget_params widget_params;

	monitor_line(MONITOR_LINE_INFO, "GET_WIDGET_PARAMS_REPLY");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	widget_params_get(&widget_params);
	widget_usb_send_message(GET_WIDGET_PARAMS_REPLY, (uint8_t *) &widget_params, sizeof(struct _widget_params));
}
コード例 #2
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * See https://github.com/OpenLightingProject/ola/blob/master/plugins/usbpro/EnttecUsbProWidget.cpp#L353
 *
 * (Label=12 \ref RDM_TIMEOUT)
 *
 */
inline static void rdm_time_out_message(void) {
	const uint16_t message_length = 0;

	monitor_line(MONITOR_LINE_INFO, "Send RDM data to HOST, l:%d", message_length);
	monitor_line(MONITOR_LINE_STATUS, "rdm_time_out_message");

	widget_usb_send_header(RDM_TIMEOUT, message_length);
	widget_usb_send_footer();

	widget_rdm_discovery_running = false;
	widget_send_rdm_packet_start = 0;
}
コード例 #3
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Receive DMX on Change (label = 8 \ref RECEIVE_DMX_ON_CHANGE)
 *
 * This message requests the Widget send a DMX packet to the PC only when the DMX values change
 * on the input port.
 *
 * By default the widget will always send, if you want to send on change it must be enabled by sending
 * this message.
 *
 * This message also reinitializes the DMX receive processing, so that if change of state reception is
 * selected, the initial received DMX data is cleared to all zeros.
 *
 */
static void widget_receive_dmx_on_change(void) {
	monitor_line(MONITOR_LINE_INFO, "RECEIVE_DMX_ON_CHANGE");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, false);

	receive_dmx_on_change = widget_data[0];

	dmx_clear_data();

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, true);

	widget_received_dmx_packet_start = hardware_micros();
}
コード例 #4
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Output Only Send DMX Packet Request (label = 6 \ref OUTPUT_ONLY_SEND_DMX_PACKET_REQUEST)
 *
 * This message requests the Widget to periodically send a DMX packet out of the Widget DMX port
 * at the configured DMX output rate. This message causes the widget to leave the DMX port direction
 * as output after each DMX packet is sent, so no DMX packets will be received as a result of this
 * request.
 *
 * The periodic DMX packet output will stop and the Widget DMX port direction will change to input
 * when the Widget receives any request message other than the Output Only Send DMX Packet
 * request, or the Get Widget Parameters request.
 *
 * @param data_length DMX data to send, beginning with the start code.
 */
void widget_send_dmx_packet_request_output_only(uint16_t data_length) {
	if (widget_send_rdm_packet_start != 0) {
		return;
	}

	monitor_line(MONITOR_LINE_INFO, "OUTPUT_ONLY_SEND_DMX_PACKET_REQUEST");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	dmx_set_port_direction(DMX_PORT_DIRECTION_OUTP, false);

	dmx_set_send_data(widget_data, data_length);

	dmx_set_port_direction(DMX_PORT_DIRECTION_OUTP, true);
}
コード例 #5
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * This function is called from the poll table in \ref main.c
 *
 * Received RMX Packet (Label=5 \ref RECEIVED_DMX_PACKET)
 *
 * The Widget sends this message to the PC unsolicited, whenever the Widget receives a DMX or RDM packet from the DMX port,
 * and the Receive DMX on Change mode (\ref receive_dmx_on_change) is 'Send always' (\ref SEND_ALWAYS).
 */
void widget_received_rdm_packet(void) {
	if ((widget_mode == MODE_DMX) || (widget_mode == MODE_RDM_SNIFFER)
			|| (receive_dmx_on_change == SEND_ON_DATA_CHANGE_ONLY)) {
		return;
	}

	const uint8_t *rdm_data = rdm_get_available();

	if (rdm_data == NULL) {
		return;
	}

	uint8_t message_length = 0;

	if (rdm_data[0] == E120_SC_RDM) {
		struct _rdm_command *p = (struct _rdm_command *) (rdm_data);
		const uint8_t command_class = p->command_class;
		message_length = p->message_length + 2;

		monitor_line(MONITOR_LINE_INFO, "Send RDM data to HOST, l:%d", message_length);
		monitor_line(MONITOR_LINE_STATUS, "RECEIVED_RDM_PACKET SC:0xCC");

		widget_usb_send_header(RECEIVED_DMX_PACKET, 1 + message_length);
		usb_send_byte(0); 	// RDM Receive status
		widget_usb_send_data(rdm_data, message_length);
		widget_usb_send_footer();

		const uint16_t param_id = (p->param_id[0] << 8) + p->param_id[1];

		if ((command_class == E120_DISCOVERY_COMMAND_RESPONSE) && (param_id != E120_DISC_MUTE)) {
			rdm_time_out_message();
		} else {
			widget_send_rdm_packet_start = 0;
		}
	} else if (rdm_data[0] == 0xFE) {
		message_length = 24;

		monitor_line(MONITOR_LINE_INFO, "Send RDM data to HOST, l:%d", message_length);
		monitor_line(MONITOR_LINE_STATUS, "RECEIVED_RDM_PACKET SC:0xFE");

		widget_usb_send_header(RECEIVED_DMX_PACKET, 1 + message_length);
		usb_send_byte(0); 	// RDM Receive status
		widget_usb_send_data(rdm_data, message_length);
		widget_usb_send_footer();

		rdm_time_out_message();
	}

	monitor_rdm_data(MONITOR_LINE_RDM_DATA, message_length, rdm_data, false);
}
コード例 #6
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Send RDM Discovery Request (Label=11 \ref SEND_RDM_DISCOVERY_REQUEST)
 *
 * This message requests the Widget to send an RDM Discovery Request packet out of the Widget
 * DMX port, and then receive an RDM Discovery Response.
 */
static void widget_send_rdm_discovery_request(uint16_t data_length) {
	monitor_line(MONITOR_LINE_INFO, "SEND_RDM_DISCOVERY_REQUEST");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	dmx_set_port_direction(DMX_PORT_DIRECTION_OUTP, false);

	rdm_send_data(widget_data, data_length);
	udelay(RDM_RESPONDER_DATA_DIRECTION_DELAY);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, true);

	widget_rdm_discovery_running = true;
	widget_send_rdm_packet_start = hardware_micros();

	monitor_rdm_data(MONITOR_LINE_RDM_DATA, data_length, widget_data, true);
}
コード例 #7
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Get Widget Serial Number Reply (Label = 10 \ref GET_WIDGET_PARAMS_REPLY)
 *
 */
static void widget_get_sn_reply(void) {
	struct _rdm_device_info_data rdm_device_info_sn;

	monitor_line(MONITOR_LINE_INFO, "GET_WIDGET_PARAMS_REPLY");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	rdm_device_info_get_sn(&rdm_device_info_sn);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, false);

	widget_usb_send_message(GET_WIDGET_SN_REPLY, rdm_device_info_sn.data, rdm_device_info_sn.length);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, true);

	widget_received_dmx_packet_start = hardware_micros();
}
コード例 #8
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Set Widget Parameters Request (Label=4 \ref SET_WIDGET_PARAMS)
 * This message sets the Widget configuration. The Widget configuration is preserved when the Widget loses power.
 *
 */
static void widget_set_params() {
	struct _widget_params widget_params;

	monitor_line(MONITOR_LINE_INFO, "SET_WIDGET_PARAMS");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, false);

	widget_params.break_time = widget_data[2];
	widget_params.mab_time = widget_data[3];
	widget_params.refresh_rate = widget_data[4];
	widget_params_set(&widget_params);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, true);

	widget_received_dmx_packet_start = hardware_micros();
}
コード例 #9
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Received DMX Change Of State Packet (Label = 9 \ref RECEIVED_DMX_COS_TYPE)
 *
 * The Widget sends one or more instances of this message to the PC unsolicited, whenever the
 * Widget receives a changed DMX packet from the DMX port, and the Receive DMX on Change
 * mode (\ref receive_dmx_on_change) is 'Send on data change only' (\ref SEND_ON_DATA_CHANGE_ONLY).
 */
void widget_received_dmx_change_of_state_packet(void) {
	if (widget_mode == MODE_RDM_SNIFFER) {
		return;
	}

	if (widget_rdm_discovery_running
			|| (DMX_PORT_DIRECTION_INP != dmx_get_port_direction())
			|| (SEND_ALWAYS == receive_dmx_on_change)) {
		return;
	}

	if (dmx_is_data_changed()) {
		monitor_line(MONITOR_LINE_INFO, "RECEIVED_DMX_COS_TYPE");
		monitor_line(MONITOR_LINE_STATUS, NULL);
		// TODO widget_received_dmx_change_of_state_packet
		monitor_line(MONITOR_LINE_INFO, "Sent changed DMX data to HOST");
	}
}
コード例 #10
0
void mode_0_init(void) {
	clear_dmx_data();

	midi_message = (const struct _midi_message *) midi_message_get();
	midi_channel = bridge_params_get_midi_channel();

	midi_active_sense_failed = (midi_get_active_sense_state() == MIDI_ACTIVE_SENSE_FAILED);

	dmx_start_address = bridge_params_get_dmx_start_address();
	dmx_max_slot = (dmx_start_address + (uint16_t) 127) <= DMX_UNIVERSE_SIZE ? (dmx_start_address + (uint16_t) 127) : DMX_UNIVERSE_SIZE + (uint16_t) 1; // SC

	dmx_set_port_direction(DMX_PORT_DIRECTION_OUTP, false);
	dmx_set_send_data(dmx_data, 1 + dmx_max_slot);	// SC + data
	dmx_set_port_direction(DMX_PORT_DIRECTION_OUTP, true);

	monitor_line(5, "Listening channel : %d %s", midi_channel, midi_channel == 0 ? "<OMNI>" : "");
	monitor_line(6, "DMX start address : %d", dmx_start_address);
	monitor_line(7, "DMX slots         : %d", dmx_max_slot);
}
コード例 #11
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * Read bytes from host
 *
 * This function is called from the poll table in \ref main.c
 */
void widget_receive_data_from_host(void) {
	if (usb_read_is_byte_available()) {
		const uint8_t c = usb_read_byte();

		if (AMF_START_CODE == c) {
			const uint8_t label = usb_read_byte();	// Label
			const uint8_t lsb = usb_read_byte();	// Data length LSB
			const uint8_t msb = usb_read_byte();	// Data length MSB
			const uint16_t data_length = ((uint16_t) ((uint16_t) msb << 8)) | ((uint16_t) lsb);

			uint16_t i;
			for (i = 0; i < data_length; i++) {
				widget_data[i] = usb_read_byte();
			}

			while ((AMF_END_CODE != usb_read_byte()) && (i++ < (sizeof(widget_data) / sizeof(widget_data[0]))))
				;

			monitor_line(MONITOR_LINE_LABEL, "L:%d:%d(%d)", label, data_length, i);

			switch (label) {
			case GET_WIDGET_PARAMS:
				widget_get_params_reply();
				break;
			case GET_WIDGET_SN_REQUEST:
				widget_get_sn_reply();
				break;
			case SET_WIDGET_PARAMS:
				widget_set_params();
				break;
			case GET_WIDGET_NAME_LABEL:
				widget_get_name_reply();
				break;
			case MANUFACTURER_LABEL:
				widget_get_manufacturer_reply();
				break;
			case OUTPUT_ONLY_SEND_DMX_PACKET_REQUEST:
				widget_send_dmx_packet_request_output_only(data_length);
				break;
			case RECEIVE_DMX_ON_CHANGE:
				widget_receive_dmx_on_change();
				break;
			case SEND_RDM_PACKET_REQUEST:
				widget_send_rdm_packet_request(data_length);
				break;
			case SEND_RDM_DISCOVERY_REQUEST:
				widget_send_rdm_discovery_request(data_length);
				break;
			default:
				break;
			}
		}
	}
}
コード例 #12
0
/**
 * @ingroup monitor
 */
void monitor_update(void) {
	const volatile struct _dmx_devices_statistics *dmx_devices_statistics = dmx_devices_get_statistics();
	const uint32_t function_count_per_second = dmx_devices_statistics->function_count - function_count_previous;
	const uint32_t run_count_per_second = dmx_devices_statistics->run_count - run_count_previous;

	monitor_time_uptime(MONITOR_LINE_TIME);
	monitor_sniffer();
	monitor_line(MONITOR_LINE_STATS, "%ld / %ld", function_count_per_second, run_count_per_second);

	function_count_previous = dmx_devices_statistics->function_count;
	run_count_previous = dmx_devices_statistics->run_count;
}
コード例 #13
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * https://wiki.openlighting.org/index.php/USB_Protocol_Extensions#Device_Name.2C_Label_.3D_78.2C_no_data
 *
 * Get Widget Name Reply (Label = 78 \ref GET_WIDGET_NAME_LABEL)
 */
static void widget_get_name_reply(void) {
	struct _rdm_device_info_data rdm_device_info_label;
	struct _widget_params_data widget_params_type_id;

	monitor_line(MONITOR_LINE_INFO, "GET_WIDGET_NAME_LABEL");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	rdm_device_info_get_label(0, &rdm_device_info_label);
	widget_params_get_type_id(&widget_params_type_id);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, false);

	widget_usb_send_header(GET_WIDGET_NAME_LABEL, widget_params_type_id.length + rdm_device_info_label.length);
	widget_usb_send_data(widget_params_type_id.data, widget_params_type_id.length);
	widget_usb_send_data(rdm_device_info_label.data, rdm_device_info_label.length);
	widget_usb_send_footer();

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, true);

	widget_received_dmx_packet_start = hardware_micros();
}
コード例 #14
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * https://wiki.openlighting.org/index.php/USB_Protocol_Extensions#Device_Manufacturer.2C_Label_.3D_77.2C_no_data
 *
 * Get Widget Manufacturer Reply (Label = 77 \ref MANUFACTURER_LABEL)
 */
static void widget_get_manufacturer_reply(void) {
	struct _rdm_device_info_data rdm_device_info_manufacturer_name;
	struct _rdm_device_info_data rdm_device_info_manufacturer_id;

	monitor_line(MONITOR_LINE_INFO, "MANUFACTURER_LABEL");
	monitor_line(MONITOR_LINE_STATUS, NULL);

	rdm_device_info_get_manufacturer_name(&rdm_device_info_manufacturer_name);
	rdm_device_info_get_manufacturer_id(&rdm_device_info_manufacturer_id);

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, false);

	widget_usb_send_header(MANUFACTURER_LABEL, rdm_device_info_manufacturer_id.length + rdm_device_info_manufacturer_name.length);
	widget_usb_send_data(rdm_device_info_manufacturer_id.data, rdm_device_info_manufacturer_id.length);
	widget_usb_send_data(rdm_device_info_manufacturer_name.data, rdm_device_info_manufacturer_name.length);
	widget_usb_send_footer();

	dmx_set_port_direction(DMX_PORT_DIRECTION_INP, true);

	widget_received_dmx_packet_start = hardware_micros();
}
コード例 #15
0
ファイル: widget.c プロジェクト: vanvught/rpidmx512
/**
 *
 * This function is called from the poll table in \ref main.c
 *
 * Received DMX Packet (Label=5 \ref RECEIVED_DMX_PACKET)
 *
 * The Widget sends this message to the PC unsolicited, whenever the Widget receives a DMX or RDM packet from the DMX port,
 * and the Receive DMX on Change mode (\ref receive_dmx_on_change) is 'Send always' (\ref SEND_ALWAYS).
 */
void widget_received_dmx_packet(void) {
	if (widget_mode == MODE_RDM_SNIFFER) {
		return;
	}

	if (widget_rdm_discovery_running
			|| (DMX_PORT_DIRECTION_INP != dmx_get_port_direction())
			|| (SEND_ON_DATA_CHANGE_ONLY == receive_dmx_on_change)) {
		return;
	}

	const uint8_t *dmx_data = dmx_get_available();

	if (dmx_data == NULL) {
		return;
	}

	const uint32_t micros_now = hardware_micros();

	if (micros_now - widget_received_dmx_packet_start < widget_received_dmx_packet_period) {
		return;
	}

	widget_received_dmx_packet_start = micros_now;

	widget_received_dmx_packet_count++;

	const struct _dmx_data *dmx_statistics = (struct _dmx_data *)dmx_data;
	const uint16_t length = (uint16_t)(dmx_statistics->statistics.slots_in_packet + 1);

	monitor_line(MONITOR_LINE_LABEL, "poll:RECEIVED_DMX_PACKET");
	monitor_line(MONITOR_LINE_INFO, "Send DMX data to HOST, %d", length);
	monitor_line(MONITOR_LINE_STATUS, NULL);

	widget_usb_send_header(RECEIVED_DMX_PACKET, length + 1);
	usb_send_byte(0); 	// DMX Receive status
	widget_usb_send_data(dmx_data, length);
	widget_usb_send_footer();
}