Пример #1
0
u_int16_t fifo_data_put(struct fifo *fifo, u_int16_t len, u_int8_t *data)
{
	if (len > fifo_available(fifo)) {
		len = fifo_available(fifo);
		fifo->irq |= FIFO_IRQ_OFLOW;
	}

	if (len + fifo->producer <= fifo->size) {
		/* easy case */
		memcpy(&fifo->data[fifo->producer], data, len);
		fifo->producer += len;
	} else {
		/* difficult: wrap around */
		u_int16_t chunk_len;

		chunk_len = fifo->size - fifo->producer;
		memcpy(&fifo->data[fifo->producer], data, chunk_len);

		memcpy(&fifo->data[0], data + chunk_len, len - chunk_len);
		fifo->producer = len - chunk_len;
	}

	fifo_check_water(fifo);

	return len;
}
Пример #2
0
static void
pci_uart_drain(int fd, enum ev_type ev, void *arg)
{
	struct pci_uart_softc *sc;
	int ch;

	sc = arg;	

	assert(fd == STDIN_FILENO);
	assert(ev == EVF_READ);
	
	/*
	 * This routine is called in the context of the mevent thread
	 * to take out the softc lock to protect against concurrent
	 * access from a vCPU i/o exit
	 */
	pthread_mutex_lock(&sc->mtx);

	if ((sc->mcr & MCR_LOOPBACK) != 0) {
		(void) ttyread();
	} else {
		while (fifo_available(&sc->rxfifo) &&
		       ((ch = ttyread()) != -1)) {
			fifo_putchar(&sc->rxfifo, ch);
		}
		pci_uart_toggle_intr(sc);
	}

	pthread_mutex_unlock(&sc->mtx);
}
Пример #3
0
void fifo_check_water(struct fifo *fifo)
{
	int avail = fifo_available(fifo);

	if (avail <= fifo->watermark)
		fifo->irq |= FIFO_IRQ_LO;
	else
		fifo->irq &= FIFO_IRQ_LO;

	if (fifo->size - avail >= fifo->watermark)
		fifo->irq |= FIFO_IRQ_HI;
	else
		fifo->irq &= FIFO_IRQ_HI;
}
Пример #4
0
/**
 * Use interrupt to reload out buffer and continue transmission
 */
void SPI0_TWI0_Handler()
{
    // event must be cleared
    SPI_EVENT_READY(my_spi) = 0;

    if (fifo_available(spi_buffer))
    {
        // enqueue next byte for transmission
        char c;
        fifo_read(&buffer, &c);
        spi_write(my_spi, c);
    }
    else
    {
        // transmission sequence completed
        spi_disable(my_spi);
    }
}
Пример #5
0
u_int16_t fifo_data_get(struct fifo *fifo, u_int16_t len, u_int8_t *data)
{
	u_int16_t avail = fifo_available(fifo);

	if (avail < len)
		len = avail;

	if (fifo->producer > fifo->consumer) {
		/* easy case */
		memcpy(data, &fifo->data[fifo->consumer], len);
	} else {
		/* difficult case: wrap */
		u_int16_t chunk_len = fifo->size - fifo->consumer;
		memcpy(data, &fifo->data[fifo->consumer], chunk_len);
		memcpy(data+chunk_len, &fifo->data[0], len - chunk_len);
	}

	fifo_check_water(fifo);

	return len;
}
Пример #6
0
int tty_read(struct inode* inode, void* ptr, off_t pos, size_t len) {
    if(unlikely(!inode || !ptr)) {
        errno = EINVAL;
        return -1;
    }
    
    if(unlikely(!inode->userdata)) {
        errno = EINVAL;
        return -1;
    }
    
    if(unlikely(!len))
        return 0;

 
    struct tty_context* tio = (struct tty_context*) inode->userdata;
    uint8_t* buf = (uint8_t*) ptr;
    int p = 0;


    if(tio->pgrp != current_task->pgid) 
        sys_exit((1 << 31) | W_STOPCODE(SIGTTIN));

    

    int fd = sys_open(TTY_DEFAULT_INPUT_DEVICE, O_RDONLY, 0);
    if(fd < 0) {
        errno = EIO;
        return -1;
    }


    if(fifo_available(&tio->in)) {
        char tmp[BUFSIZ];
        for(int j = 0; (j = fifo_read(&tio->in, tmp, sizeof(tmp))) > 0;)
            fifo_write(&tio->uin, tmp, j);
    }
    

    while(p < len) {
        uint8_t ch;
        if(fifo_available(&tio->uin))
            fifo_read(&tio->uin, &ch, sizeof(ch));
        else
            ch = process_keyboard(inode, tio, fd, &p);



        switch(ch) {
            case 0:
                continue;
            case '\b':
            case '\x7f':
                if(tio->ios.c_lflag & ICANON) {
                    if(p > 0) {
                        fifo_peek(&tio->in, 1);
                        p--;
                        
                        if(tio->ios.c_lflag & ECHOE)
                            ch = '\b';
                        else
                            ch = '\x7f';

                        if(tio->ios.c_lflag & ECHO)
                            tty_output_write(inode, &ch, 0, 1);
                    }

                    continue;
                } 

                /* No processing */
                ch = '\b';
                break;
            default:
                break;
        }


        if(unlikely(ch < 32)) {
            for(int i = 0; i < NCCS; i++) {
                if(ch != tio->ios.c_cc[i])
                    continue;


                fifo_write(&tio->in, &ch, 1);
                p++;

                ch = 0;
                break;
            }

            if(unlikely(!ch))
                continue;
        }



        if(!(tio->ios.c_iflag & IGNCR)) {
            if(ch == '\n')
                break;
        }


        char utf8[UTF8_MAX_LENGTH];
        size_t utf8len = ucs2_to_utf8((int32_t) ch, utf8);
        
        fifo_write(&tio->in, utf8, utf8len);
        p += utf8len;

        if(tio->ios.c_lflag & ECHO)
            tty_output_write(inode, utf8, 0, utf8len);           
    }



    if(p < len) {
        if(!(tio->ios.c_iflag & IGNCR)) {
            char ch = '\n';
            fifo_write(&tio->in, &ch, 1);
            p++;


            if((tio->ios.c_lflag & ECHO) || (tio->ios.c_lflag & ICANON && tio->ios.c_lflag & ECHONL))
                tty_output_write(inode, &ch, 0, 1);
        }
    } else
        p = len;
    


    if(fifo_available(&tio->in))
        fifo_read(&tio->in, buf, p);
    
    
    sys_close(fd);
    return p;
}