示例#1
0
文件: uart.c 项目: onitake/aversive
/** 
 * transmit next character of fifo if any, and call the event function.
 * This function is executed with intr locked.
 */
void uart_send_next_char(uint8_t num)
{
#ifdef CONFIG_MODULE_UART_9BITS
	if (uart_getconf_nbits(num) == 9) {
		int elt = 0;

		/* for 9 bits, it uses 2 places in the fifo */
		if (CIRBUF_GET_LEN(&g_tx_fifo[num]) < 2) {
			cbi(*uart_regs[num].REGISTER_FOR_UART_IE, UDRIE);
			return;
		}

		cirbuf_get_buf_tail(&g_tx_fifo[num], (char *)&elt, 2);
		cirbuf_del_buf_tail(&g_tx_fifo[num], 2);

		uart_set_udr_9bits(num, elt);
		sbi(*uart_regs[num].REGISTER_FOR_UART_IE, UDRIE);
	}
	else /* 5, 6, 7 or 8 bits */
#endif /* CONFIG_MODULE_UART_9BITS */
	{ 
		char elt = 0;

		if (CIRBUF_IS_EMPTY(&g_tx_fifo[num])) {
			cbi(*uart_regs[num].REGISTER_FOR_UART_IE, UDRIE);
			return;
		}

		elt = cirbuf_get_tail(&g_tx_fifo[num]);
		cirbuf_del_tail(&g_tx_fifo[num]);
		uart_set_udr(num, elt);
		sbi(*uart_regs[num].REGISTER_FOR_UART_IE, UDRIE);
	}
}
示例#2
0
cirbuf_int
cirbuf_add_buf_tail(struct cirbuf * cbuf, const char * c, cirbuf_uint n)
{
	cirbuf_uint e;

	if (!n || n > CIRBUF_GET_FREELEN(cbuf))
		return -EINVAL;

	e = CIRBUF_IS_EMPTY(cbuf) ? 1 : 0;
	
	if (n < cbuf->maxlen - cbuf->end - 1 + e) {
		dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->end + !e, n);
		memcpy(cbuf->buf + cbuf->end + !e, c, n);
	}
	else {
		dprintf("s[%d] -> d[%d] (%d)\n", cbuf->end + !e, 0, cbuf->maxlen - cbuf->end - 1 + e);
		dprintf("s[%d] -> d[%d] (%d)\n", cbuf->maxlen - cbuf->end - 1 + e, 0, n - cbuf->maxlen + cbuf->end + 1 - e);
		memcpy(cbuf->buf + cbuf->end + !e, c, cbuf->maxlen - cbuf->end - 1 + e);
		memcpy(cbuf->buf, c + cbuf->maxlen - cbuf->end - 1 + e, n - cbuf->maxlen + cbuf->end + 1 - e);
	}
	cbuf->len += n;
	cbuf->end += n - e;
	cbuf->end %= cbuf->maxlen;
	return n;
}
示例#3
0
cirbuf_int
cirbuf_del_tail_safe(struct cirbuf * cbuf)
{
	if (cbuf && !CIRBUF_IS_EMPTY(cbuf)) {
		__cirbuf_del_tail(cbuf);
		return 0;
	}
	return -EINVAL;
}
示例#4
0
static inline void
__cirbuf_del_tail(struct cirbuf * cbuf)
{
	cbuf->len --;
	if (!CIRBUF_IS_EMPTY(cbuf)) {
		cbuf->end  += (cbuf->maxlen - 1);
		cbuf->end %= cbuf->maxlen;
	}
}
示例#5
0
/* get a char from the receive fifo */
int uart_recv_nowait(uint8_t num)
{
	char elt = 0;
	uint8_t flags;
	
	IRQ_LOCK(flags);
	if( !CIRBUF_IS_EMPTY(&g_rx_fifo[num]) ) {
		elt = cirbuf_get_tail(&g_rx_fifo[num]);
		cirbuf_del_tail(&g_rx_fifo[num]);
		IRQ_UNLOCK(flags);
		return (int)elt;
	}
	IRQ_UNLOCK(flags);
	return (-1);
}
示例#6
0
cirbuf_int
cirbuf_del_buf_tail(struct cirbuf * cbuf, cirbuf_uint size)
{
	if (!size || size > CIRBUF_GET_LEN(cbuf))
		return -EINVAL;

	cbuf->len -= size;
	if (CIRBUF_IS_EMPTY(cbuf)) {
		cbuf->end  += (cbuf->maxlen - size + 1);
		cbuf->end %= cbuf->maxlen;
	}
	else {
		cbuf->end  += (cbuf->maxlen - size);
		cbuf->end %= cbuf->maxlen;
	}
	return 0;
}