Beispiel #1
0
static vsf_err_t
vsf_malstream_read_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsf_malstream_t *malstream = (struct vsf_malstream_t *)pt->user_data;
	struct vsfmal_t *mal = malstream->mal;
	struct vsf_stream_t *stream = (struct vsf_stream_t *)malstream->mbufstream;
	uint64_t cur_addr;
	vsf_err_t err;

	vsfsm_pt_begin(pt);

	mal->op_block_size = mal->drv->block_size(mal, malstream->addr, 0,
												VSFMAL_OP_READ);
	if (mal->op_block_size != malstream->mbufstream->mem.multibuf.size)
	{
		return VSFERR_BUG;
	}

	mal->pt.user_data = mal;
	malstream->offset = 0;
	while (malstream->offset < malstream->size)
	{
		while (stream_get_free_size(stream) < mal->op_block_size)
		{
			vsfsm_pt_wfe(pt, VSF_MALSTREAM_ON_INOUT);
		}

		mal->pt.state = 0;
		vsfsm_pt_entry(pt);
		cur_addr = malstream->addr + malstream->offset;
		err = mal->drv->read(&mal->pt, evt, cur_addr,
				vsf_multibuf_get_empty(&malstream->mbufstream->mem.multibuf),
				mal->op_block_size);
		if (err > 0) return err; else if (err < 0) goto end;
		vsf_multibuf_push(&malstream->mbufstream->mem.multibuf);
		malstream->offset += mal->op_block_size;
		if (malstream->offset >= malstream->size)
		{
			// fix before callback
			stream->callback_tx.on_inout = NULL;
		}
		if (stream->rx_ready && (stream->callback_rx.on_inout != NULL))
		{
			stream->callback_rx.on_inout(stream->callback_rx.param);
		}
	}

end:
	if (malstream->cb.on_finish != NULL)
	{
		malstream->cb.on_finish(malstream->cb.param);
	}

	vsfsm_pt_end(pt);
	return VSFERR_NONE;
}
Beispiel #2
0
static struct vsfsm_state_t *
vsfusbd_CDCData_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt)
{
	struct vsfusbd_CDC_param_t *param =
						(struct vsfusbd_CDC_param_t *)sm->user_data;
	struct vsfusbd_device_t *device = param->device;

	switch (evt)
	{
	case VSFSM_EVT_INIT:
		param->stream_tx->callback_rx.param = param;
		param->stream_tx->callback_rx.on_inout =
							vsfusbd_CDCData_streamtx_on_in;
		param->stream_tx->callback_rx.on_connect =
							vsfusbd_CDCData_streamtx_on_txconn;
		param->stream_rx->callback_tx.param = param;
		param->stream_rx->callback_tx.on_inout =
							vsfusbd_CDCData_streamrx_on_out;
		param->stream_rx->callback_tx.on_connect =
							vsfusbd_CDCData_streamrx_on_rxconn;

		param->out_enable = false;
		param->in_enable = false;
		break;
	case VSFUSBD_CDC_EVT_STREAMTX_ONCONN:
		vsfusbd_set_IN_handler(device, param->ep_in,
										vsfusbd_CDCData_IN_hanlder);
		break;
	case VSFUSBD_CDC_EVT_STREAMRX_ONCONN:
		vsfusbd_set_OUT_handler(device, param->ep_out,
										vsfusbd_CDCData_OUT_hanlder);
		vsfsm_post_evt(sm, VSFUSBD_CDC_EVT_STREAMRX_ONOUT);
		break;
	case VSFUSBD_CDC_EVT_STREAMTX_ONIN:
		if (!param->in_enable)
		{
			param->in_enable = true;
			vsfusbd_CDCData_IN_hanlder(param->device, param->ep_in);
		}
		break;
	case VSFUSBD_CDC_EVT_STREAMRX_ONOUT:
		if (!param->out_enable &&
			(stream_get_free_size(param->stream_rx) >=
					device->drv->ep.get_OUT_epsize(param->ep_out)))
		{
			param->out_enable = true;
			device->drv->ep.enable_OUT(param->ep_out);
		}
		break;
	}

	return NULL;
}
Beispiel #3
0
uint32_t debug(const char *format, ...)
{
	va_list ap;
	struct vsf_buffer_t buffer;
	uint32_t size_avail, size_out, i, colon;
	uint8_t *ptr;

	if (debug_stream == NULL)
		return 0;

	size_avail = stream_get_free_size(debug_stream);
	if (size_avail < 3)
		return 0;

	// TODO: manual parse format
	va_start(ap, format);
	size_out = vsnprintf((char *)debug_info, VSFCFG_DEBUG_INFO_PARSE_LEN, format, ap);
	va_end(ap);

	if (size_out < 3)
		return 0;

	ptr = debug_info;
	i = 0;
	colon = 0;
	while (ptr < debug_info + size_out - 3)
	{
		if ((*ptr == ':') && (colon++ > 0))
			break;

		if ((*ptr == '/') || (*ptr == '\\'))
			 i = ptr - debug_info + 1;
		ptr++;
	}

	size_avail = min(size_avail, size_out - i);
	debug_info[i + size_avail - 2] = '\r';
	debug_info[i + size_avail - 1] = '\n';

	buffer.buffer = debug_info + i;
	buffer.size = size_avail;

	return stream_write(debug_stream, &buffer);
}
Beispiel #4
0
static vsf_err_t vsfusbd_CDCData_OUT_hanlder(struct vsfusbd_device_t *device,
												uint8_t ep)
{
	struct vsfusbd_config_t *config = &device->config[device->configuration];
	int8_t iface = config->ep_OUT_iface_map[ep];
	struct vsfusbd_CDC_param_t *param = NULL;
	uint16_t pkg_size, ep_size;
	uint8_t buffer[64];
	struct vsf_buffer_t rx_buffer;

	if (iface < 0)
	{
		return VSFERR_FAIL;
	}
	param = (struct vsfusbd_CDC_param_t *)config->iface[iface].protocol_param;
	if (NULL == param)
	{
		return VSFERR_FAIL;
	}

	ep_size = device->drv->ep.get_OUT_epsize(ep);
	pkg_size = device->drv->ep.get_OUT_count(ep);
	if (pkg_size > ep_size)
	{
		return VSFERR_FAIL;
	}
	device->drv->ep.read_OUT_buffer(ep, buffer, pkg_size);

	rx_buffer.buffer = buffer;
	rx_buffer.size = pkg_size;
	stream_write(param->stream_rx, &rx_buffer);

	if (stream_get_free_size(param->stream_rx) < ep_size)
	{
		param->out_enable = false;
	}
	else
	{
		device->drv->ep.enable_OUT(ep);
	}

	return VSFERR_NONE;
}
Beispiel #5
0
static vsf_err_t vsfusbd_CDCData_class_poll(uint8_t iface,
        struct vsfusbd_device_t *device)
{
    struct vsfusbd_config_t *config = &device->config[device->configuration];
    struct vsfusbd_CDC_param_t *param =
        (struct vsfusbd_CDC_param_t *)config->iface[iface].protocol_param;

    if (NULL == param)
    {
        return VSFERR_FAIL;
    }

    if (!param->out_enable)
    {
        uint16_t ep_size = device->drv->ep.get_OUT_epsize(param->ep_out);

        if (stream_get_free_size(param->stream_tx) >= ep_size)
        {
            param->out_enable = true;
            device->drv->ep.enable_OUT(param->ep_out);
        }
    }
    return VSFERR_NONE;
}
Beispiel #6
0
// vsfshell_output_thread is used to process the events
// 		from the receiver of the stream_tx
vsf_err_t vsfshell_output_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt,
									const char *format, ...)
{
	struct vsfshell_t *shell = (struct vsfshell_t *)pt->user_data;
	uint32_t str_len, size_avail;
	struct vsf_buffer_t buffer;
	va_list ap;
	char *printf_buff;
	uint32_t printf_size;
	
	vsfsm_pt_begin(pt);
	// get lock here
	if (vsfsm_crit_enter(&shell->output_crit, pt->sm))
	{
		vsfsm_pt_wfe(pt, VSFSHELL_EVT_OUTPUT_CRIT_AVAIL);
	}
	shell->output_sm = pt->sm;
	
	if (shell->output_interrupted && (pt->sm == &shell->sm))
	{
		// is vsfshell_input_thread is interrupted
		// 		and current pt is vsfshell_input_thread
		// then output the VSFSHELL_PROMPT and the original commandline
		shell->output_interrupted = false;
		
		size_avail = stream_get_free_size(shell->stream_tx);
		while (size_avail < strlen(VSFSHELL_PROMPT))
		{
			vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONOUT);
			size_avail = stream_get_free_size(shell->stream_tx);
		}
		buffer.buffer = (uint8_t *)VSFSHELL_PROMPT;
		buffer.size = strlen(VSFSHELL_PROMPT);
		stream_write(shell->stream_tx, &buffer);
		shell->prompted = true;
		
		shell->tbuffer.buffer.buffer[shell->tbuffer.position] = '\0';
		shell->printf_pos = (char *)shell->tbuffer.buffer.buffer;
		str_len = strlen(shell->printf_pos);
		while (str_len > 0)
		{
			size_avail = stream_get_free_size(shell->stream_tx);
			if (!size_avail)
			{
				vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONOUT);
				size_avail = stream_get_free_size(shell->stream_tx);
				str_len = strlen(shell->printf_pos);
			}
			
			if (size_avail)
			{
				buffer.buffer = (uint8_t *)shell->printf_pos;
				buffer.size = min(str_len, size_avail);
				buffer.size = stream_write(shell->stream_tx, &buffer);
				shell->printf_pos += buffer.size;
				str_len = strlen(shell->printf_pos);
			}
		}
	}
	
	va_start(ap, format);
	printf_size = sizeof(shell->printf_buff);
	printf_buff = shell->printf_buff;
	if (pt->sm != shell->input_sm)
	{
		// if current pt is not frontend, then add a new line
		if (shell->input_sm == &shell->sm)
		{
			// if current frontend pt is vsfshell_input_thread
			// 		then set output_interrupted, so that current command line
			// 		input will be recovered later
			shell->output_interrupted = true;
		}
		if (shell->prompted)
		{
			// add a new line if prompt is outputed
			strcpy(shell->printf_buff, VSFSHELL_LINEEND);
			printf_size -= strlen(VSFSHELL_LINEEND);
			printf_buff += strlen(VSFSHELL_LINEEND);
			shell->prompted = false;
		}
	}
	str_len = vsnprintf(printf_buff, printf_size, format, ap);
	va_end(ap);
	shell->printf_pos = shell->printf_buff;
	
	while (str_len > 0)
	{
		size_avail = stream_get_free_size(shell->stream_tx);
		if (!size_avail)
		{
			vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONOUT);
			size_avail = stream_get_free_size(shell->stream_tx);
			str_len = strlen(shell->printf_pos);
		}
		
		if (size_avail)
		{
			buffer.buffer = (uint8_t *)shell->printf_pos;
			buffer.size = min(str_len, size_avail);
			buffer.size = stream_write(shell->stream_tx, &buffer);
			shell->printf_pos += buffer.size;
			str_len = strlen(shell->printf_pos);
		}
	}
	shell->output_sm = NULL;
	vsfsm_crit_leave(&shell->output_crit);
	vsfsm_pt_end(pt);
	
	return VSFERR_NONE;
}