Esempio n. 1
0
static void udi_cdc_tx_send(void)
{
	irqflags_t flags;
	uint8_t buf_sel_trans;
	bool b_short_packet;

	if (udi_cdc_tx_trans_ongoing) {
		return; // Already on going or wait next SOF to send next data
	}
	if (udd_is_high_speed()) {
		if (udi_cdc_tx_sof_num == udd_get_micro_frame_number()) {
			return; // Wait next SOF to send next data
		}
	}else{
		if (udi_cdc_tx_sof_num == udd_get_frame_number()) {
			return; // Wait next SOF to send next data
		}
	}

	flags = cpu_irq_save();	// to protect udi_cdc_tx_buf_sel
	buf_sel_trans = udi_cdc_tx_buf_sel;
	if (!udi_cdc_tx_both_buf_to_send) {
		// Send current Buffer
		// and switch the current buffer
		udi_cdc_tx_buf_sel = (buf_sel_trans==0)?1:0;
	}else{
		// Send the other Buffer
		// and no switch the current buffer
		buf_sel_trans = (buf_sel_trans==0)?1:0;
	}
	udi_cdc_tx_trans_ongoing = true;
	cpu_irq_restore(flags);

	b_short_packet = (udi_cdc_tx_buf_nb[buf_sel_trans] != UDI_CDC_TX_BUFFERS);
	if (b_short_packet) {
		if (udd_is_high_speed()) {
			udi_cdc_tx_sof_num = udd_get_micro_frame_number();
		}else{
			udi_cdc_tx_sof_num = udd_get_frame_number();
		}
	}else{
		udi_cdc_tx_sof_num = 0; // Force next transfer without wait SOF
	}

	// Send the buffer with enable of short packet
	udd_ep_run( UDI_CDC_DATA_EP_IN,
					b_short_packet,
					udi_cdc_tx_buf[buf_sel_trans],
					udi_cdc_tx_buf_nb[buf_sel_trans],
					udi_cdc_data_sent);
}
static void udi_cdc_tx_send(uint8_t port)
{
	irqflags_t flags;
	uint8_t buf_sel_trans;
	bool b_short_packet;
	udd_ep_id_t ep;
	static uint16_t sof_zlp_counter = 0;

#if UDI_CDC_PORT_NB == 1 // To optimize code
	port = 0;
#endif

	if (udi_cdc_tx_trans_ongoing[port]) {
		return; // Already on going or wait next SOF to send next data
	}
	if (udd_is_high_speed()) {
		if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) {
			return; // Wait next SOF to send next data
		}
	}else{
		if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) {
			return; // Wait next SOF to send next data
		}
	}

	flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel
	buf_sel_trans = udi_cdc_tx_buf_sel[port];
	if (udi_cdc_tx_buf_nb[port][buf_sel_trans] == 0) {
		sof_zlp_counter++;
		if (((!udd_is_high_speed()) && (sof_zlp_counter < 100))
				|| (udd_is_high_speed() && (sof_zlp_counter < 800))) {
			cpu_irq_restore(flags);
			return;
		}
	}
	sof_zlp_counter = 0;

	if (!udi_cdc_tx_both_buf_to_send[port]) {
		// Send current Buffer
		// and switch the current buffer
		udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0;
	}else{
		// Send the other Buffer
		// and no switch the current buffer
		buf_sel_trans = (buf_sel_trans==0)?1:0;
	}
	udi_cdc_tx_trans_ongoing[port] = true;
	cpu_irq_restore(flags);

	b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS);
	if (b_short_packet) {
		if (udd_is_high_speed()) {
			udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number();
		}else{
			udi_cdc_tx_sof_num[port] = udd_get_frame_number();
		}
	}else{
		udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF
	}

	// Send the buffer with enable of short packet
	switch (port) {
#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \
	case index: \
		ep = UDI_CDC_DATA_EP_IN_##index; \
		break;
	MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~)
#undef UDI_CDC_PORT_TO_DATA_EP_IN
	default:
		ep = UDI_CDC_DATA_EP_IN_0;
		break;
	}
	udd_ep_run( ep,
			b_short_packet,
			udi_cdc_tx_buf[port][buf_sel_trans],
			udi_cdc_tx_buf_nb[port][buf_sel_trans],
			udi_cdc_data_sent);
}