void udi_cdc_data_recevied(udd_ep_status_t status, iram_size_t n)
{
	if (UDD_EP_TRANSFER_OK != status) {
		// Abort reception
		return;
	}
	if (0 == n) {
		// Empty packet then restart reception on same buffer
		udi_cdc_rx_start();
		return;
	}
	// Update the buffer's number
	udi_cdc_rx_buf_nb[udi_cdc_rx_trans_sel] = n;

	// Go to next buffer
	udi_cdc_rx_trans_sel = (udi_cdc_rx_trans_sel + 1) % 2;
	// Check if next buffer is free
	if (udi_cdc_rx_trans_sel == udi_cdc_rx_buf_sel) {
		// No buffer free; stop reception
		udi_cdc_rx_trans_sel = UDI_CDC_TRANS_HALTED;
	} else {
		// Restart reception on next buffer
		udi_cdc_rx_start();
	}
}
static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep)
{
	uint8_t buf_sel_trans;
	uint8_t port;

	switch (ep) {
#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \
	case UDI_CDC_DATA_EP_OUT_##index: \
		port = index; \
		break;
	MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~)
#undef UDI_CDC_DATA_EP_OUT_TO_PORT
	default:
		port = 0;
		break;
	}

	if (UDD_EP_TRANSFER_OK != status) {
		// Abort reception
		return;
	}
	buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0;
	if (!n) {
		udd_ep_run( ep,
				true,
				udi_cdc_rx_buf[port][buf_sel_trans],
				UDI_CDC_RX_BUFFERS,
				udi_cdc_data_received);
		return;
	}
	udi_cdc_rx_buf_nb[port][buf_sel_trans] = n;
	udi_cdc_rx_trans_ongoing[port] = false;
	udi_cdc_rx_start(port);
}
예제 #3
0
파일: udi_cdc.c 프로젝트: JohsBL/MobRob
iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size)
{
	uint8_t *ptr_buf = (uint8_t *)buf;
	iram_size_t copy_nb;

udi_cdc_read_buf_loop_wait:
	// Check avaliable data
	while (udi_cdc_rx_pos >= udi_cdc_rx_buf_nb[udi_cdc_rx_buf_sel]) {
		if (!udi_cdc_running) {
			return size;
		}
		goto udi_cdc_read_buf_loop_wait;
	}

	// Read data
	copy_nb = udi_cdc_rx_buf_nb[udi_cdc_rx_buf_sel] - udi_cdc_rx_pos;
	if (copy_nb>size) {
		copy_nb = size;
	}
	memcpy(ptr_buf, &udi_cdc_tx_buf[udi_cdc_rx_buf_sel][udi_cdc_rx_pos], copy_nb);
	udi_cdc_rx_pos += copy_nb;
	ptr_buf += copy_nb;
	size -= copy_nb;
	udi_cdc_rx_start();

	if (size) {
		goto udi_cdc_read_buf_loop_wait;
	}
	return 0;
}
예제 #4
0
파일: udi_cdc.c 프로젝트: JohsBL/MobRob
int udi_cdc_getc(void)
{
	int rx_data = 0;
	bool b_databit_9;

	b_databit_9 = (9 == udi_cdc_line_coding.bDataBits);

udi_cdc_getc_process_one_byte:
	// Check avaliable data
	while (udi_cdc_rx_pos >= udi_cdc_rx_buf_nb[udi_cdc_rx_buf_sel]) {
		if (!udi_cdc_running) {
			return 0;
		}
		goto udi_cdc_getc_process_one_byte;
	}

	// Read data
	rx_data |= udi_cdc_rx_buf[udi_cdc_rx_buf_sel][udi_cdc_rx_pos];
	udi_cdc_rx_pos++;

	udi_cdc_rx_start();

	if (b_databit_9) {
		// Receive MSB
		b_databit_9 = false;
		rx_data = rx_data << 8;
		goto udi_cdc_getc_process_one_byte;
	}
	return rx_data;
}
예제 #5
0
iram_size_t udi_cdc_multi_read_buf(uint8_t port, int* buf, iram_size_t size)
{
	uint8_t *ptr_buf = (uint8_t *)buf;
	iram_size_t copy_nb;
	uint16_t pos;
	uint8_t buf_sel;

udi_cdc_read_buf_loop_wait:
	// Check avaliable data
	pos = udi_cdc_rx_pos[PORT];
	buf_sel = udi_cdc_rx_buf_sel[PORT];
	while (pos >= udi_cdc_rx_buf_nb[PORT][buf_sel]) {
		if (!udi_cdc_running[PORT]) {
			return size;
		}
		goto udi_cdc_read_buf_loop_wait;
	}

	// Read data
	copy_nb = udi_cdc_rx_buf_nb[PORT][buf_sel] - pos;
	if (copy_nb>size) {
		copy_nb = size;
	}
	memcpy(ptr_buf, &udi_cdc_rx_buf[PORT][buf_sel][pos], copy_nb);
	udi_cdc_rx_pos[PORT] += copy_nb;
	ptr_buf += copy_nb;
	size -= copy_nb;
	udi_cdc_rx_start(PORT);

	if (size) {
		goto udi_cdc_read_buf_loop_wait;
	}
	return 0;
}
예제 #6
0
int udi_cdc_multi_getc(uint8_t port)
{
	int rx_data = 0;
	bool b_databit_9;
	uint16_t pos;
	uint8_t buf_sel;

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

udi_cdc_getc_process_one_byte:
	// Check avaliable data
	pos = udi_cdc_rx_pos[PORT];
	buf_sel = udi_cdc_rx_buf_sel[PORT];
	while (pos >= udi_cdc_rx_buf_nb[PORT][buf_sel]) {
		if (!udi_cdc_running[PORT]) {
			return 0;
		}
		goto udi_cdc_getc_process_one_byte;
	}

	// Read data
	rx_data |= udi_cdc_rx_buf[PORT][buf_sel][pos];
	udi_cdc_rx_pos[PORT] = pos+1;

	udi_cdc_rx_start(PORT);

	if (b_databit_9) {
		// Receive MSB
		b_databit_9 = false;
		rx_data = rx_data << 8;
		goto udi_cdc_getc_process_one_byte;
	}
	return rx_data;
}
예제 #7
0
파일: udi_cdc.c 프로젝트: JohsBL/MobRob
void udi_cdc_data_recevied(udd_ep_status_t status, iram_size_t n)
{
	uint8_t buf_sel_trans;

	if (UDD_EP_TRANSFER_OK != status) {
		// Abort reception
		return;
	}
	buf_sel_trans = (udi_cdc_rx_buf_sel==0)?1:0;
	udi_cdc_rx_buf_nb[buf_sel_trans] = n;
	udi_cdc_rx_trans_ongoing = false;
	udi_cdc_rx_start();
}
예제 #8
0
파일: udi_cdc.c 프로젝트: JohsBL/MobRob
bool udi_cdc_data_enable(void)
{
	// Initialize TX management
	udi_cdc_tx_trans_ongoing = false;
	udi_cdc_tx_both_buf_to_send = false;
	udi_cdc_tx_buf_sel = 0;
	udi_cdc_tx_buf_nb[0] = 0;
	udi_cdc_tx_buf_nb[1] = 0;
	udi_cdc_tx_sof_num = 0;
	udi_cdc_tx_send();

	// Initialize RX management
	udi_cdc_rx_trans_ongoing = false;
	udi_cdc_rx_buf_sel = 0;
	udi_cdc_rx_buf_nb[0] = 0;
	udi_cdc_rx_pos = 0;
	udi_cdc_running = udi_cdc_rx_start();
	return udi_cdc_running;
}
예제 #9
0
iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size)
{
	irqflags_t flags;
	uint8_t *ptr_buf = (uint8_t *)buf;
	iram_size_t copy_nb;
	uint16_t pos;
	uint8_t buf_sel;
	bool again;

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

udi_cdc_read_buf_loop_wait:
	// Check available data
	flags = cpu_irq_save();
	pos = udi_cdc_rx_pos[port];
	buf_sel = udi_cdc_rx_buf_sel[port];
	again = pos >= udi_cdc_rx_buf_nb[port][buf_sel];
	cpu_irq_restore(flags);
	while (again) {
		if (!udi_cdc_data_running) {
			return size;
		}
		goto udi_cdc_read_buf_loop_wait;
	}

	// Read data
	copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos;
	if (copy_nb>size) {
		copy_nb = size;
	}
	memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb);
	udi_cdc_rx_pos[port] += copy_nb;
	ptr_buf += copy_nb;
	size -= copy_nb;
	udi_cdc_rx_start(port);

	if (size) {
		goto udi_cdc_read_buf_loop_wait;
	}
	return 0;
}
예제 #10
0
int udi_cdc_multi_getc(uint8_t port)
{
	irqflags_t flags;
	int rx_data = 0;
	bool b_databit_9;
	uint16_t pos;
	uint8_t buf_sel;
	bool again;

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

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

udi_cdc_getc_process_one_byte:
	// Check available data
	flags = cpu_irq_save();
	pos = udi_cdc_rx_pos[port];
	buf_sel = udi_cdc_rx_buf_sel[port];
	again = pos >= udi_cdc_rx_buf_nb[port][buf_sel];
	cpu_irq_restore(flags);
	while (again) {
		if (!udi_cdc_data_running) {
			return 0;
		}
		goto udi_cdc_getc_process_one_byte;
	}

	// Read data
	rx_data |= udi_cdc_rx_buf[port][buf_sel][pos];
	udi_cdc_rx_pos[port] = pos+1;

	udi_cdc_rx_start(port);

	if (b_databit_9) {
		// Receive MSB
		b_databit_9 = false;
		rx_data = rx_data << 8;
		goto udi_cdc_getc_process_one_byte;
	}
	return rx_data;
}
예제 #11
0
static bool udi_cdc_data_enable_common(uint8_t port)
{
	// Initialize TX management
	udi_cdc_tx_trans_ongoing[PORT] = false;
	udi_cdc_tx_both_buf_to_send[PORT] = false;
	udi_cdc_tx_buf_sel[PORT] = 0;
	udi_cdc_tx_buf_nb[PORT][0] = 0;
	udi_cdc_tx_buf_nb[PORT][1] = 0;
	udi_cdc_tx_sof_num[PORT] = 0;
	udi_cdc_tx_send(PORT);

	// Initialize RX management
	udi_cdc_rx_trans_ongoing[PORT] = false;
	udi_cdc_rx_buf_sel[PORT] = 0;
	udi_cdc_rx_buf_nb[PORT][0] = 0;
	udi_cdc_rx_pos[PORT] = 0;
	udi_cdc_running[PORT] = udi_cdc_rx_start(PORT);
	return udi_cdc_running[PORT];
}
예제 #12
0
static void udi_cdc_data_received_common(uint8_t port, udd_ep_status_t status, iram_size_t n)
{
	uint8_t buf_sel_trans;

	if (UDD_EP_TRANSFER_OK != status) {
		// Abort reception
		return;
	}
	buf_sel_trans = (udi_cdc_rx_buf_sel[PORT]==0)?1:0;
	if (!n) {
		udd_ep_run( UDI_CDC_DATA_EP_OUTS[PORT],
				true,
				udi_cdc_rx_buf[PORT][buf_sel_trans],
				UDI_CDC_RX_BUFFERS,
				udi_cdc_data_received_callbacks[PORT]);
		return;
	}
	udi_cdc_rx_buf_nb[PORT][buf_sel_trans] = n;
	udi_cdc_rx_trans_ongoing[PORT] = false;
	udi_cdc_rx_start(PORT);
}
bool udi_cdc_data_enable(void)
{
	// Initialize control signal management
	udi_cdc_state = CPU_TO_LE16(0);
	uid_cdc_state_msg.value = CPU_TO_LE16(0);


	// Initialize TX management
	udi_cdc_tx_buf_nb[0] = 0;
	udi_cdc_tx_buf_nb[1] = 0;
	udi_cdc_tx_buf_sel = 0;
	udi_cdc_tx_trans_sel = UDI_CDC_TRANS_HALTED;

	// Initialize RX management
	udi_cdc_rx_buf_nb[0] = 0;
	udi_cdc_rx_buf_nb[1] = 0;
	udi_cdc_rx_pos = 0;
	udi_cdc_rx_buf_sel = 0;
	udi_cdc_rx_trans_sel = 0;
	return udi_cdc_rx_start();
}
예제 #14
0
static iram_size_t udi_cdc_multi_read_no_polling(uint8_t port, void* buf, iram_size_t size)
{
	uint8_t *ptr_buf = (uint8_t *)buf;
	iram_size_t nb_avail_data;
	uint16_t pos;
	uint8_t buf_sel;
	irqflags_t flags;

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

	//Data interface not started... exit
	if (!udi_cdc_data_running) {
		return 0;
	}
	
	//Get number of available data
	// Check available data
	flags = cpu_irq_save(); // to protect udi_cdc_rx_pos & udi_cdc_rx_buf_sel
	pos = udi_cdc_rx_pos[port];
	buf_sel = udi_cdc_rx_buf_sel[port];
	nb_avail_data = udi_cdc_rx_buf_nb[port][buf_sel] - pos;
	cpu_irq_restore(flags);
	//If the buffer contains less than the requested number of data,
	//adjust read size
	if(nb_avail_data<size) {
		size = nb_avail_data;
	}
	if(size>0) {
		memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], size);
		flags = cpu_irq_save(); // to protect udi_cdc_rx_pos
		udi_cdc_rx_pos[port] += size;
		cpu_irq_restore(flags);
		
		ptr_buf += size;
		udi_cdc_rx_start(port);
	}
	return(nb_avail_data);
}
int udi_cdc_getc(void)
{
	int rx_data = 0;
	bool b_databit_9;

	b_databit_9 = (9 == udi_cdc_line_coding.bDataBits);

udi_cdc_getc_process_one_byte:
	// Waiting for data
	while (!udi_cdc_is_rx_ready()) {
		if (UDI_CDC_TRANS_HALTED == udi_cdc_rx_trans_sel)
			return 0;	// Error system
	}

	// Read data
	rx_data |= udi_cdc_rx_buf[udi_cdc_rx_buf_sel][udi_cdc_rx_pos];
	udi_cdc_rx_pos++;

	// Check if buffer empty
	if (udi_cdc_rx_pos == udi_cdc_rx_buf_nb[udi_cdc_rx_buf_sel]) {
		// Initialize again current buffer
		udi_cdc_rx_buf_nb[udi_cdc_rx_buf_sel] = 0;
		// Switch to next buffer
		udi_cdc_rx_pos = 0;
		udi_cdc_rx_buf_sel = (udi_cdc_rx_buf_sel + 1) % 2;
		// Check if reception is halted
		if (UDI_CDC_TRANS_HALTED == udi_cdc_rx_trans_sel) {
			// Restart RX reception
			udi_cdc_rx_trans_sel = (udi_cdc_rx_buf_sel + 1) % 2;
			udi_cdc_rx_start();
		}
	}
	if (b_databit_9) {
		// Receive MSB
		b_databit_9 = false;
		rx_data = rx_data << 8;
		goto udi_cdc_getc_process_one_byte;
	}
	return rx_data;
}
예제 #16
0
bool udi_cdc_data_enable(void)
{
	uint8_t port;

#if UDI_CDC_PORT_NB == 1 // To optimize code
	port = 0;
	udi_cdc_nb_data_enabled = 0;
#else
	if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) {
		udi_cdc_nb_data_enabled = 0;
	}
	port = udi_cdc_nb_data_enabled;
#endif

	// Initialize TX management
	udi_cdc_tx_trans_ongoing[port] = false;
	udi_cdc_tx_both_buf_to_send[port] = false;
	udi_cdc_tx_buf_sel[port] = 0;
	udi_cdc_tx_buf_nb[port][0] = 0;
	udi_cdc_tx_buf_nb[port][1] = 0;
	udi_cdc_tx_sof_num[port] = 0;
	udi_cdc_tx_send(port);

	// Initialize RX management
	udi_cdc_rx_trans_ongoing[port] = false;
	udi_cdc_rx_buf_sel[port] = 0;
	udi_cdc_rx_buf_nb[port][0] = 0;
	udi_cdc_rx_buf_nb[port][1] = 0;
	udi_cdc_rx_pos[port] = 0;
	if (!udi_cdc_rx_start(port)) {
		return false;
	}
	udi_cdc_nb_data_enabled++;
	if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) {
		udi_cdc_data_running = true;
	}
	return true;
}