/** * 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); } }
/* 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); }
/* test cmdline_cirbuf char add/del functions */ static int test_cirbuf_char_add_del(void) { struct cirbuf cb; char buf[CMDLINE_TEST_BUFSIZE]; char tmp[CMDLINE_TEST_BUFSIZE]; /* clear buffer */ memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); /* * initialize circular buffer */ if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { printf("Error: failed to initialize circular buffer!\n"); return -1; } /* * try to delete something from cirbuf. since it's empty, * these should fail. */ if (cirbuf_del_head_safe(&cb) == 0) { printf("Error: deleting from empty cirbuf head succeeded!\n"); return -1; } if (cirbuf_del_tail_safe(&cb) == 0) { printf("Error: deleting from empty cirbuf tail succeeded!\n"); return -1; } /* * add, verify and delete. these should pass. */ if (cirbuf_add_head_safe(&cb,'h') < 0) { printf("Error: adding to cirbuf head failed!\n"); return -1; } if (cirbuf_get_head(&cb) != 'h') { printf("Error: wrong head content!\n"); return -1; } if (cirbuf_del_head_safe(&cb) < 0) { printf("Error: deleting from cirbuf head failed!\n"); return -1; } if (cirbuf_add_tail_safe(&cb,'t') < 0) { printf("Error: adding to cirbuf tail failed!\n"); return -1; } if (cirbuf_get_tail(&cb) != 't') { printf("Error: wrong tail content!\n"); return -1; } if (cirbuf_del_tail_safe(&cb) < 0) { printf("Error: deleting from cirbuf tail failed!\n"); return -1; } /* do the same for unsafe versions. those are void. */ cirbuf_add_head(&cb,'h'); if (cirbuf_get_head(&cb) != 'h') { printf("Error: wrong head content!\n"); return -1; } cirbuf_del_head(&cb); /* test if char has been deleted. we can't call cirbuf_get_head * because it's unsafe, but we can call cirbuf_get_buf_head. */ if (cirbuf_get_buf_head(&cb, tmp, 1) > 0) { printf("Error: buffer should have been empty!\n"); return -1; } cirbuf_add_tail(&cb,'t'); if (cirbuf_get_tail(&cb) != 't') { printf("Error: wrong tail content!\n"); return -1; } cirbuf_del_tail(&cb); /* test if char has been deleted. we can't call cirbuf_get_tail * because it's unsafe, but we can call cirbuf_get_buf_tail. */ if (cirbuf_get_buf_tail(&cb, tmp, 1) > 0) { printf("Error: buffer should have been empty!\n"); return -1; } return 0; }