コード例 #1
0
int udi_cdc_multi_putc(uint8_t port, int value)
{
	irqflags_t flags;
	bool b_databit_9;
	uint8_t buf_sel;

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

	b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits);

udi_cdc_putc_process_one_byte:
	// Check available space
	if (!udi_cdc_multi_is_tx_ready(port)) {
		if (!udi_cdc_data_running) {
			return false;
		}
		goto udi_cdc_putc_process_one_byte;
	}

	// Write value
	flags = cpu_irq_save();
	buf_sel = udi_cdc_tx_buf_sel[port];
	udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value;
	cpu_irq_restore(flags);

	if (b_databit_9) {
		// Send MSB
		b_databit_9 = false;
		value = value >> 8;
		goto udi_cdc_putc_process_one_byte;
	}
	return true;
}
コード例 #2
0
ファイル: udi_cdc.c プロジェクト: DJGCrusader/TinyArmTroller
int udi_cdc_multi_putc(uint8_t port, int value)
{
	irqflags_t flags;
	bool b_databit_9;
	uint8_t buf_sel;

	b_databit_9 = (9 == udi_cdc_line_coding[PORT].bDataBits);

udi_cdc_putc_process_one_byte:
	// Check avaliable space
	if (!udi_cdc_multi_is_tx_ready(PORT)) {
		if (!udi_cdc_running[PORT]) {
			return false;
		}
		goto udi_cdc_putc_process_one_byte;
	}

	// Write value
	flags = cpu_irq_save();
	buf_sel = udi_cdc_tx_buf_sel[PORT];
	udi_cdc_tx_buf[PORT][buf_sel][udi_cdc_tx_buf_nb[PORT][buf_sel]++] = value;
	cpu_irq_restore(flags);

	if (b_databit_9) {
		// Send MSB
		b_databit_9 = false;
		value = value >> 8;
		goto udi_cdc_putc_process_one_byte;
	}
	return true;
}
コード例 #3
0
ファイル: udi_cdc.c プロジェクト: HashFast/hashfast-uc
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size)
{
	irqflags_t flags;
	uint8_t buf_sel;
	uint16_t buf_nb;
	iram_size_t copy_nb;
	uint8_t *ptr_buf = (uint8_t *)buf;

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

	if (9 == udi_cdc_line_coding[port].bDataBits) {
		size *=2;
	}

    hashfast_init_udi_cdc_write_timeout();

udi_cdc_write_buf_loop_wait:
	// Check available space
	if (!udi_cdc_multi_is_tx_ready(port)) {
		if (!udi_cdc_data_running) {
			return size;
		}
		if (hashfast_udi_cdc_timeout())
			return size;
		goto udi_cdc_write_buf_loop_wait;
	}

	// Write values
	flags = cpu_irq_save();
	buf_sel = udi_cdc_tx_buf_sel[port];
	buf_nb = udi_cdc_tx_buf_nb[port][buf_sel];
	copy_nb = UDI_CDC_TX_BUFFERS - buf_nb;
	if (copy_nb > size) {
		copy_nb = size;
	}
	memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb);
	udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb;
	cpu_irq_restore(flags);

	// Update buffer pointer
	ptr_buf = ptr_buf + copy_nb;
	size -= copy_nb;

	if (size) {
		if (hashfast_udi_cdc_timeout())
			return(size);
		goto udi_cdc_write_buf_loop_wait;
	}

	return 0;
}
コード例 #4
0
ファイル: uart_sam.c プロジェクト: Timvrakas/samd21_gcc
static void usart_handler(uint8_t port)
{
	Usart* usart = get_usart(port);
	uint32_t sr = usart_get_status(usart);
	if (sr & US_CSR_RXRDY) {
		// Data received
		ui_com_tx_start();
		uint32_t value;
		bool b_error = usart_read(usart, &value) ||
			(sr & (US_CSR_FRAME | US_CSR_TIMEOUT | US_CSR_PARE));
		if (b_error) {
			usart_reset_rx(usart);
			usart_enable_rx(usart);
			udi_cdc_multi_signal_framing_error(port);
			ui_com_error();
		}
		// Transfer UART RX fifo to CDC TX
		if (!udi_cdc_multi_is_tx_ready(port)) {
			// Fifo full
			udi_cdc_multi_signal_overrun(port);
			ui_com_overflow();
		} else {
			udi_cdc_multi_putc(port, value);
		}
		ui_com_tx_stop();
		return;
	}

	if (sr & US_CSR_TXRDY) {
		// Data send
		if (udi_cdc_multi_is_rx_ready(port)) {
			// Transmit next data
			ui_com_rx_start();
			int c = udi_cdc_multi_getc(port);
			usart_write(usart, c);
			
		} else {
			// Fifo empty then Stop UART transmission
			usart_disable_tx(usart);
			usart_disable_interrupt(usart, US_IDR_TXRDY);
			ui_com_rx_stop();
		}
	}
}
コード例 #5
0
ファイル: udi_cdc.c プロジェクト: DJGCrusader/TinyArmTroller
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const int* buf, iram_size_t size)
{
	irqflags_t flags;
	uint8_t buf_sel;
	uint16_t buf_nb;
	iram_size_t copy_nb;
	uint8_t *ptr_buf = (uint8_t *)buf;

	if (9 == udi_cdc_line_coding[PORT].bDataBits) {
		size *=2;
	}

udi_cdc_write_buf_loop_wait:
	// Check avaliable space
	if (!udi_cdc_multi_is_tx_ready(PORT)) {
		if (!udi_cdc_running[PORT]) {
			return size;
		}
		goto udi_cdc_write_buf_loop_wait;
	}

	// Write values
	flags = cpu_irq_save();
	buf_sel = udi_cdc_tx_buf_sel[PORT];
	buf_nb = udi_cdc_tx_buf_nb[PORT][buf_sel];
	copy_nb = UDI_CDC_TX_BUFFERS - buf_nb;
	if (copy_nb>size) {
		copy_nb = size;
	}
	memcpy(&udi_cdc_tx_buf[PORT][buf_sel][buf_nb], ptr_buf, copy_nb);
	udi_cdc_tx_buf_nb[PORT][buf_sel] = buf_nb + copy_nb;
	cpu_irq_restore(flags);

	// Update buffer pointer
	ptr_buf = ptr_buf + copy_nb;
	size -= copy_nb;

	if (size) {
		goto udi_cdc_write_buf_loop_wait;
	}

	return 0;
}
コード例 #6
0
bool udi_cdc_is_tx_ready(void)
{
	return udi_cdc_multi_is_tx_ready(0);
}