Esempio n. 1
0
static void
serial_data_rcv_done(serial_channel *chan, int chars_rcvd)
{
    cbuf_t *cbuf = &chan->in_cbuf;

    cbuf->put += chars_rcvd;
    cbuf->nb += chars_rcvd;

    if (cbuf->put == cbuf->len) cbuf->put = 0;

    CYG_ASSERT(cbuf->nb <= cbuf->len, "Buffer overflow");
    CYG_ASSERT(cbuf->put < cbuf->len, "Invalid put ptr");
    CYG_ASSERT(cbuf->get < cbuf->len, "Invalid get ptr");

    if (cbuf->waiting) {
        cbuf->waiting = false;
        cyg_drv_cond_signal(&cbuf->wait);
    }
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
    // If we've hit the high water mark, tell the other side to stop
    if ( cbuf->nb >= cbuf->high_water ) {
        throttle_rx( chan, false );
    }
#endif
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
    // Wake up any pending selectors if we have
    // put some data into a previously empty buffer.
    if (chars_rcvd == cbuf->nb)
        cyg_selwakeup( &cbuf->selinfo );
#endif

#ifdef CYGDBG_USE_ASSERTS
    cbuf->block_mode_xfer_running = false;
#endif
}
Esempio n. 2
0
// DSPI DSR
static void dspi_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
    cyg_spi_freescale_dspi_bus_t* dspi_bus = (cyg_spi_freescale_dspi_bus_t*) data;

    cyg_drv_dsr_lock();
    cyg_drv_cond_signal(&dspi_bus->transfer_done);
    cyg_drv_dsr_unlock();
}
Esempio n. 3
0
static void disk_transfer_done(struct disk_channel *chan, Cyg_ErrNo res)
{
    disk_controller    *ctlr = chan->controller;    

    ctlr->result = res;
    
    cyg_drv_cond_signal( &ctlr->async );
}
Esempio n. 4
0
static void
usbs_devtab_callback(void* arg, int result)
{
    usbs_callback_data* callback_data = (usbs_callback_data*) arg;
    callback_data->result       = result;
    callback_data->completed    = true;
    cyg_drv_cond_signal(&(callback_data->signal));
}
Esempio n. 5
0
/**
*
* QSPI bus DSR handler
*
* @param    vector     - Number of ISR
* @param    data       - Pointer to data structure (with driver handle)
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
    cyg_qspi_xc7z_bus_t * qspi_bus = (cyg_qspi_xc7z_bus_t *)data;
    
    // Transfer ended
    qspi_bus->transfer_end = true;
    cyg_drv_cond_signal(&qspi_bus->transfer_cond);
}
Esempio n. 6
0
//==========================================================================
// DSR signals data
//==========================================================================
static void
lpc2xxx_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
{
    cyg_lpc2xxx_i2c_extra* extra = (cyg_lpc2xxx_i2c_extra*)data;
    if(extra->i2c_flag)
    {
        cyg_drv_cond_signal(&extra->i2c_wait);
    }
}
Esempio n. 7
0
static Cyg_ErrNo 
disk_set_config(cyg_io_handle_t  handle, 
                cyg_uint32       key, 
                const void      *xbuf, 
                cyg_uint32      *len)
{
    cyg_devtab_entry_t *t    = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan = (disk_channel *) t->priv;
    disk_controller    *ctlr = chan->controller;    
    cyg_disk_info_t    *info = chan->info;
    disk_funs          *funs = chan->funs;
    Cyg_ErrNo res = ENOERR;
    
    cyg_drv_mutex_lock( &ctlr->lock );

    while( ctlr->busy )
        cyg_drv_cond_wait( &ctlr->queue );

    if (info->connected && chan->valid)
    {
        ctlr->busy = true;
        
        D(("disk set config key=%d\n", key)); 

        switch ( key )
        {
        case CYG_IO_SET_CONFIG_DISK_MOUNT:
            chan->mounts++;
            info->mounts++;
            D(("disk mount: chan %d disk %d\n",chan->mounts, info->mounts));
            break;
            
        case CYG_IO_SET_CONFIG_DISK_UMOUNT:
            chan->mounts--;
            info->mounts--;
            D(("disk umount: chan %d disk %d\n",chan->mounts, info->mounts));            
            break;
            
        default:
            break;
        }
        
        // pass down to lower layers
        res = (funs->set_config)(chan, key, xbuf, len);
        
        ctlr->busy = false;
        cyg_drv_cond_signal( &ctlr->queue );
    }
    else
        res = -EINVAL;
    
    cyg_drv_mutex_unlock( &ctlr->lock );

    return res;
    
}
Esempio n. 8
0
static Cyg_ErrNo 
disk_get_config(cyg_io_handle_t  handle, 
                cyg_uint32       key, 
                void            *xbuf,
                cyg_uint32      *len)
{
    cyg_devtab_entry_t *t    = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan = (disk_channel *) t->priv;
    disk_controller    *ctlr = chan->controller;    
    cyg_disk_info_t    *info = chan->info;
    cyg_disk_info_t    *buf  = (cyg_disk_info_t *) xbuf;
    disk_funs          *funs = chan->funs;
    Cyg_ErrNo res = ENOERR;
 
    cyg_drv_mutex_lock( &ctlr->lock );

    while( ctlr->busy )
        cyg_drv_cond_wait( &ctlr->queue );

    if (info->connected && chan->valid)
    {
        ctlr->busy = true;
    
        D(("disk get config key=%d\n", key)); 
    
        switch (key) {
        case CYG_IO_GET_CONFIG_DISK_INFO:
            if (*len < sizeof(cyg_disk_info_t)) {
                res = -EINVAL;
                break;
            }
            D(("chan->info->block_size %u\n", chan->info->block_size ));
            D(("chan->info->blocks_num %u\n", chan->info->blocks_num ));
            D(("chan->info->phys_block_size %u\n", chan->info->phys_block_size ));
            *buf = *chan->info;
            *len = sizeof(cyg_disk_info_t);
            break;       

        default:
            // pass down to lower layers
            res = (funs->get_config)(chan, key, xbuf, len);
        }
        
        ctlr->busy = false;
        cyg_drv_cond_signal( &ctlr->queue );
    }
    else
        res = -EINVAL;

    cyg_drv_mutex_unlock( &ctlr->lock );    
    
    return res;
}
Esempio n. 9
0
// DSR signals data
static void zynq_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
{
#ifdef ZYNQ_I2C_DEBUG
    DPRINTF("DSR executed\n");
#endif
    cyg_zynq_i2c_extra* extra = (cyg_zynq_i2c_extra*)data;
    if(extra->i2c_flag)
    {
        cyg_drv_cond_signal(&extra->i2c_wait);
    }
    cyg_drv_interrupt_unmask(vec);
}
Esempio n. 10
0
static void 
spi_at91_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
    cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *) data;
    cyg_uint32 stat;
    
    // Read the status register and 
    // check for transfer completition
    
    HAL_READ_UINT32(AT91_SPI+AT91_SPI_SR, stat);

    if((stat & AT91_SPI_SR_ENDRX) && (stat & AT91_SPI_SR_ENDTX))
    {
        // Transfer ended  
        spi_bus->transfer_end = true;
        cyg_drv_cond_signal(&spi_bus->transfer_cond);
    }
    else
    {
        // Transfer still in progress - unmask the SPI 
        // int so we can get more SPI int events
        cyg_drv_interrupt_unmask(vector);
    }
}
Esempio n. 11
0
static void
serial_rcv_char(serial_channel *chan, unsigned char c)
{
    cbuf_t *cbuf = &chan->in_cbuf;

#ifdef CYGPKG_NET_BLUEZ_STACK
	if(chan->receive)//clyu
	{
		extern unsigned char bluetooth_buf[];
		int len = 0;
		struct tty_ldisc *ldisc = chan->tty_ldisc;
		if(ldisc && ldisc->receive_buf && cbuf->nb)
		{
			diag_printf("bluetooth\n");
			if(cbuf->put < cbuf->get)
			{
				memcpy(bluetooth_buf, cbuf->data + cbuf->get, cbuf->len - cbuf->get);
				len = cbuf->len - cbuf->get;
				//ldisc->receive_buf(serial_driver, cbuf->data + cbuf->get, (char*)cbuf, cbuf->len - cbuf->get);
				cbuf->nb -= len;
				cbuf->get = 0;
			}
			memcpy(bluetooth_buf + len, cbuf->data + cbuf->get, cbuf->put);
			len += cbuf->put;
			cbuf->get = cbuf->put;
			cbuf->nb -= len;
			//ldisc->receive_buf(serial_driver, cbuf->data + cbuf->get, (char*)cbuf, cbuf->nb); 
			ldisc->receive_buf(serial_driver, bluetooth_buf, (char*)cbuf, len); 
			
		}
		chan->receive = 0;
		return;
	}
#endif

#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
    CYG_ASSERT(false == cbuf->block_mode_xfer_running,
               "Attempting char rcv while block transfer is running");
#endif
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
    // for software flow control, if the driver returns one of the characters
    // we act on it and then drop it (the app must not see it)
    if ( chan->config.flags & CYGNUM_SERIAL_FLOW_XONXOFF_TX ) {
        if ( c == CYGDAT_IO_SERIAL_FLOW_CONTROL_XOFF_CHAR ) {
            throttle_tx( chan );
            return; // it wasn't a "real" character
        } else if ( c == CYGDAT_IO_SERIAL_FLOW_CONTROL_XON_CHAR ) {
            restart_tx( chan );
            return; // it wasn't a "real" character
        }
    }
#endif    
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
    // If we've hit the high water mark, tell the other side to stop
    if ( cbuf->nb >= cbuf->high_water ) {
        throttle_rx( chan, false );
    }
#endif
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
    // Wake up any pending selectors if we are about to
    // put some data into a previously empty buffer.
    if( cbuf->nb == 0 )
        cyg_selwakeup( &cbuf->selinfo );
#endif

    // If the flow control is not enabled/sufficient and the buffer is
    // already full, just throw new characters away.

    if ( cbuf->nb < cbuf->len ) {
        cbuf->data[cbuf->put++] = c;
        if (cbuf->put == cbuf->len) cbuf->put = 0;
        cbuf->nb++;
    } // note trailing else
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
    else {
        // Overrun. Report the error.
        cyg_serial_line_status_t stat;
        stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
        serial_indicate_status(chan, &stat);
    }
#endif

    if (cbuf->waiting) {
#ifdef XX_CYGDBG_DIAG_BUF
            extern int enable_diag_uart;
            int _enable = enable_diag_uart;
            int _time, _stime;
            externC cyg_tick_count_t cyg_current_time(void);
            enable_diag_uart = 0;
            HAL_CLOCK_READ(&_time);
            _stime = (int)cyg_current_time();
            diag_printf("Signal reader - time: %x.%x\n", _stime, _time);
            enable_diag_uart = _enable;
#endif // CYGDBG_DIAG_BUF
        cbuf->waiting = false;
        cyg_drv_cond_signal(&cbuf->wait);
    }
    
}
Esempio n. 12
0
static Cyg_ErrNo 
serial_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *xbuf,
                  cyg_uint32 *len)
{
    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
    serial_channel *chan = (serial_channel *)t->priv;
    cyg_serial_info_t *buf = (cyg_serial_info_t *)xbuf;
    Cyg_ErrNo res = ENOERR;
    cbuf_t *out_cbuf = &chan->out_cbuf;
    cbuf_t *in_cbuf = &chan->in_cbuf;
    serial_funs *funs = chan->funs;


    switch (key) {
    case CYG_IO_GET_CONFIG_SERIAL_INFO:
        if (*len < sizeof(cyg_serial_info_t)) {
            return -EINVAL;
        }
        *buf = chan->config;
        *len = sizeof(chan->config);
        break;       

    case CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO:
        // return rx/tx buffer sizes and counts
        {
            cyg_serial_buf_info_t *p;
            if (*len < sizeof(cyg_serial_buf_info_t))
                return -EINVAL;
          
            *len = sizeof(cyg_serial_buf_info_t);
            p = (cyg_serial_buf_info_t *)xbuf;
            
            p->rx_bufsize = in_cbuf->len;
            if (p->rx_bufsize)
                p->rx_count = in_cbuf->nb;
            else
                p->rx_count = 0;
            
            p->tx_bufsize = out_cbuf->len;
            if (p->tx_bufsize)
                p->tx_count = out_cbuf->nb;
            else
                p->tx_count = 0;
        }
      break;
      
    case CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN:
// Wait for any pending output to complete
        if (out_cbuf->len == 0) break;  // Nothing to do if not buffered
        cyg_drv_mutex_lock(&out_cbuf->lock);  // Stop any further output processing
        cyg_drv_dsr_lock();//dsr lock, it will lead to dsr interrupt can't be called; and serial_xmt_char can't be called forever
        while (out_cbuf->pending || (out_cbuf->nb > 0)) {
            //clyu
            //these codes will race with serial_xmt_char(cyg_drv_cond_broadcast)
            //if modify w90n740_serial_putc(...) return true always, these code will not run
            out_cbuf->waiting = true;

            if(!cyg_drv_cond_wait(&out_cbuf->wait) )
            	res = -EINTR;

        }
        cyg_drv_dsr_unlock();
        cyg_drv_mutex_unlock(&out_cbuf->lock);
        break;

    case CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH:
        // Flush any buffered input
        if (in_cbuf->len == 0) break;  // Nothing to do if not buffered
        cyg_drv_mutex_lock(&in_cbuf->lock);  // Stop any further input processing
        cyg_drv_dsr_lock();
        if (in_cbuf->waiting) {
            in_cbuf->abort = true;
            cyg_drv_cond_signal(&in_cbuf->wait);
            in_cbuf->waiting = false;
        }
        in_cbuf->get = in_cbuf->put = in_cbuf->nb = 0;  // Flush buffered input
        cyg_drv_dsr_unlock();
        cyg_drv_mutex_unlock(&in_cbuf->lock);
        break;

    case CYG_IO_GET_CONFIG_SERIAL_ABORT:
        // Abort any outstanding I/O, including blocked reads
        // Caution - assumed to be called from 'timeout' (i.e. DSR) code
        if (in_cbuf->len != 0) {
            in_cbuf->abort = true;
            cyg_drv_cond_signal(&in_cbuf->wait);
        }
        if (out_cbuf->len != 0) {
            out_cbuf->abort = true;
            cyg_drv_cond_signal(&out_cbuf->wait);
        }
        break;

    case CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH:
// Throw away any pending output
        if (out_cbuf->len == 0) break;  // Nothing to do if not buffered
        cyg_drv_mutex_lock(&out_cbuf->lock);  // Stop any further output processing
        cyg_drv_dsr_lock();
        if (out_cbuf->nb > 0) {
            out_cbuf->get = out_cbuf->put = out_cbuf->nb = 0;  // Empties queue!
            (funs->stop_xmit)(chan);  // Done with transmit
        }
        if (out_cbuf->waiting) {
            out_cbuf->abort = true;
            cyg_drv_cond_signal(&out_cbuf->wait);
            out_cbuf->waiting = false;
        }
        cyg_drv_dsr_unlock();
        cyg_drv_mutex_unlock(&out_cbuf->lock);
        break;

#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
    case CYG_IO_GET_CONFIG_READ_BLOCKING:
        if (*len < sizeof(cyg_uint32)) {
            return -EINVAL;
        }
        *(cyg_uint32*)xbuf = (in_cbuf->blocking) ? 1 : 0;
        break;

    case CYG_IO_GET_CONFIG_WRITE_BLOCKING:
        if (*len < sizeof(cyg_uint32)) {
            return -EINVAL;
        }
        *(cyg_uint32*)xbuf = (out_cbuf->blocking) ? 1 : 0;
        break;
#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING

    default:
        res = -EINVAL;
    }
    return res;
}
Esempio n. 13
0
static Cyg_ErrNo
disk_bwrite(cyg_io_handle_t  handle,
            const void      *buf,
            cyg_uint32      *len,   // In blocks
            cyg_uint32       pos)   // In blocks
{
    cyg_devtab_entry_t *t    = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan = (disk_channel *) t->priv;
    disk_controller    *ctlr = chan->controller;
    disk_funs          *funs = chan->funs;
    cyg_disk_info_t    *info = chan->info;
    cyg_uint32  size = *len;
    cyg_uint8  *bbuf = (cyg_uint8 * const) buf;
    Cyg_ErrNo   res  = ENOERR;
    cyg_uint32  last;

    cyg_drv_mutex_lock( &ctlr->lock );

    while( ctlr->busy )
        cyg_drv_cond_wait( &ctlr->queue );

    if (info->connected && chan->valid)
    {
        ctlr->busy = true;

        if (NULL != chan->partition)
        {
            pos += chan->partition->start;
            last = chan->partition->end;
        }
        else
        {
            last = info->blocks_num-1;
        }

        D(("disk write block=%d len=%d buf=%p\n", pos, *len, buf));

        while( size > 0 )
        {
            cyg_uint32 tfr = size;

            if (pos > last)
            {
                res = -EIO;
                goto done;
            }

            if( tfr > info->ident.max_transfer )
                tfr = info->ident.max_transfer;

            ctlr->result = -EWOULDBLOCK;

            cyg_drv_dsr_lock();

            res = (funs->write)(chan, (void*)bbuf, tfr, pos);

            if( res == -EWOULDBLOCK )
            {
                // If the driver replys EWOULDBLOCK, then the transfer is
                // being handled asynchronously and when it is finished it
                // will call disk_transfer_done(). This will wake us up here
                // to continue.

                while( ctlr->result == -EWOULDBLOCK )
                    cyg_drv_cond_wait( &ctlr->async );

                res = ctlr->result;
            }

            cyg_drv_dsr_unlock();

            if (ENOERR != res)
                goto done;

            if (!info->connected)
            {
                res = -EINVAL;
                goto done;
            }

            bbuf        += tfr * info->block_size;
            pos         += tfr;
            size        -= tfr;

        }

        ctlr->busy = false;
        cyg_drv_cond_signal( &ctlr->queue );
    }
    else
        res = -EINVAL;

done:

    cyg_drv_mutex_unlock( &ctlr->lock );
#ifdef CYGPKG_KERNEL
    cyg_thread_yield();
#endif

    *len -= size;
    return res;
}