Exemple #1
0
__interrupt void USCI0TX_ISR(void)
{
    if (uart_start_tx()!=0)
    {
        UART_TX_LED_OFF();
        IE2 &= ~UCA0TXIE;		// Disable USCI_A0 TX interrupt
    }
}
Exemple #2
0
// uart put char function
int uart_putc(char c)
{
#ifdef UART_TX_BUFMASK
	unsigned int new_ptr = (uart_tx_inptr+1)&UART_TX_BUFMASK;
#else
	int new_ptr = (uart_tx_inptr+1)%UART_TX_BUFLEN;
#endif
	if (new_ptr==uart_tx_outptr) return -1; // buffer full
	uart_tx_buffer[new_ptr] = c;
	uart_tx_inptr=new_ptr;
	if (!uart_tx_transmitt) return uart_start_tx(); // return ok (if buffer not empty)
	return 0; // return ok
}
static void
console_queue_char(char ch)
{
    struct console_tty *ct = &console_tty;
    int sr;

    OS_ENTER_CRITICAL(sr);
    while (CONSOLE_HEAD_INC(&ct->ct_tx) == ct->ct_tx.cr_tail) {
        /* TX needs to drain */
        uart_start_tx(ct->ct_dev);
        OS_EXIT_CRITICAL(sr);
        if (os_started()) {
            os_time_delay(1);
        }
        OS_ENTER_CRITICAL(sr);
    }
    console_add_char(&ct->ct_tx, ch);
    OS_EXIT_CRITICAL(sr);
}
size_t
console_file_write(void *arg, const char *str, size_t cnt)
{
    struct console_tty *ct = &console_tty;
    int i;

    if (!ct->ct_write_char) {
        return cnt;
    }
    for (i = 0; i < cnt; i++) {
        if (str[i] == '\n') {
            ct->ct_write_char('\r');
        }
        ct->ct_write_char(str[i]);
    }
    if (cnt > 0) {
        console_is_midline = str[cnt - 1] != '\n';
    }
    uart_start_tx(ct->ct_dev);
    return cnt;
}
static int
console_rx_char(void *arg, uint8_t data)
{
    struct console_tty *ct = (struct console_tty *)arg;
    struct console_ring *tx = &ct->ct_tx;
    struct console_ring *rx = &ct->ct_rx;
    int tx_space = 0;
    int i;
#if MYNEWT_VAL(CONSOLE_HIST_ENABLE)
    uint8_t tx_buf[MYNEWT_VAL(CONSOLE_RX_BUF_SIZE)];
#else
    uint8_t tx_buf[3];
#endif

    if (CONSOLE_HEAD_INC(&ct->ct_rx) == ct->ct_rx.cr_tail) {
        /*
         * RX queue full. Reader must drain this.
         */
        if (ct->ct_rx_cb) {
            ct->ct_rx_cb();
        }
        return -1;
    }

    /* echo */
    switch (data) {
    case '\r':
    case '\n':
        /*
         * linefeed
         */
        tx_buf[0] = '\n';
        tx_buf[1] = '\r';
        tx_space = 2;
        console_add_char(rx, '\n');
#if MYNEWT_VAL(CONSOLE_HIST_ENABLE)
        console_hist_add(rx);
#endif
        if (ct->ct_rx_cb) {
            ct->ct_rx_cb();
        }
        break;
    case CONSOLE_ESC:
        ct->ct_esc_seq = 1;
        goto out;
    case '[':
        if (ct->ct_esc_seq == 1) {
            ct->ct_esc_seq = 2;
            goto out;
        } else {
            goto queue_char;
        }
        break;
    case CONSOLE_LEFT:
        if (ct->ct_esc_seq == 2) {
            goto backspace;
        } else {
            goto queue_char;
        }
        break;
    case CONSOLE_UP:
    case CONSOLE_DOWN:
        if (ct->ct_esc_seq != 2) {
            goto queue_char;
        }
#if MYNEWT_VAL(CONSOLE_HIST_ENABLE)
        tx_space = console_hist_move(rx, tx_buf, data);
        tx_buf[tx_space] = 0;
        ct->ct_esc_seq = 0;
        /*
         * when moving up, stop on oldest history entry
         * when moving down, let it delete input before leaving...
         */
        if (data == CONSOLE_UP && tx_space == 0) {
            goto out;
        }
        if (!ct->ct_echo_off) {
            /* HACK: clean line by backspacing up to maximum possible space */
            for (i = 0; i < MYNEWT_VAL(CONSOLE_TX_BUF_SIZE); i++) {
                if (console_buf_space(tx) < 3) {
                    console_tx_flush(ct, 3);
                }
                console_add_char(tx, '\b');
                console_add_char(tx, ' ');
                console_add_char(tx, '\b');
                uart_start_tx(ct->ct_dev);
            }
            if (tx_space == 0) {
                goto out;
            }
        } else {
            goto queue_char;
        }
        break;
#else
        ct->ct_esc_seq = 0;
        goto out;
#endif
    case CONSOLE_RIGHT:
        if (ct->ct_esc_seq == 2) {
            data = ' '; /* add space */
        }
        goto queue_char;
    case '\b':
    case CONSOLE_DEL:
backspace:
        /*
         * backspace
         */
        ct->ct_esc_seq = 0;
        if (console_pull_char_head(rx) == 0) {
            /*
             * Only wipe out char if we can pull stuff off from head.
             */
            tx_buf[0] = '\b';
            tx_buf[1] = ' ';
            tx_buf[2] = '\b';
            tx_space = 3;
        } else {
            goto out;
        }
        break;
    default:
queue_char:
        tx_buf[0] = data;
        tx_space = 1;
        ct->ct_esc_seq = 0;
        console_add_char(rx, data);
        break;
    }
    if (!ct->ct_echo_off) {
        if (console_buf_space(tx) < tx_space) {
            console_tx_flush(ct, tx_space);
        }
        for (i = 0; i < tx_space; i++) {
            console_add_char(tx, tx_buf[i]);
        }
        uart_start_tx(ct->ct_dev);
    }
out:
    return 0;
}
/*
 * Called by mgmt to queue packet out to UART.
 */
static int
nmgr_uart_out(struct nmgr_transport *nt, struct os_mbuf *m)
{
    struct nmgr_uart_state *nus = (struct nmgr_uart_state *)nt;
    struct os_mbuf_pkthdr *mpkt;
    struct os_mbuf *n;
    char tmp_buf[12];
    uint16_t crc;
    char *dst;
    int off;
    int boff;
    int slen;
    int sr;
    int rc;
    int last;
    int tx_sz;

    assert(OS_MBUF_IS_PKTHDR(m));
    mpkt = OS_MBUF_PKTHDR(m);

    off = 0;
    crc = CRC16_INITIAL_CRC;
    for (n = m; n; n = SLIST_NEXT(n, om_next)) {
        crc = crc16_ccitt(crc, n->om_data, n->om_len);
    }
    crc = htons(crc);
    dst = os_mbuf_extend(m, sizeof(crc));
    if (!dst) {
        goto err;
    }
    memcpy(dst, &crc, sizeof(crc));

    n = os_msys_get(SHELL_NLIP_MAX_FRAME, 0);
    if (!n || OS_MBUF_TRAILINGSPACE(n) < 32) {
        goto err;
    }

    while (off < mpkt->omp_len) {
        tx_sz = 2;
        dst = os_mbuf_extend(n, 2);
        if (off == 0) {
            *(uint16_t *)dst = htons(SHELL_NLIP_PKT);
            *(uint16_t *)tmp_buf = htons(mpkt->omp_len);
            boff = 2;
        } else {
            *(uint16_t *)dst = htons(SHELL_NLIP_DATA);
            boff = 0;
        }

        while (off < mpkt->omp_len) {
            slen = mpkt->omp_len - off;
            last = 1;
            if (slen > sizeof(tmp_buf) + boff) {
                slen = sizeof(tmp_buf) - boff;
                last = 0;
            }
            if (tx_sz + BASE64_ENCODE_SIZE(slen + boff) >= 124) {
                break;
            }
            rc = os_mbuf_copydata(m, off, slen, tmp_buf + boff);
            assert(rc == 0);

            off += slen;
            slen += boff;

            dst = os_mbuf_extend(n, BASE64_ENCODE_SIZE(slen));
            if (!dst) {
                goto err;
            }
            tx_sz += base64_encode(tmp_buf, slen, dst, last);
            boff = 0;
        }

        if (os_mbuf_append(n, "\n", 1)) {
            goto err;
        }
    }

    os_mbuf_free_chain(m);
    OS_ENTER_CRITICAL(sr);
    if (!nus->nus_tx) {
        nus->nus_tx = n;
        uart_start_tx(nus->nus_dev);
    } else {
        os_mbuf_concat(nus->nus_tx, n);
    }
    OS_EXIT_CRITICAL(sr);

    return 0;
err:
    os_mbuf_free_chain(m);
    os_mbuf_free_chain(n);
    return -1;
}