⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loop_serial.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
// And finally, the device table entries:

#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL0
DEVTAB_ENTRY(loop_serial_io0, 
             CYGDAT_IO_SERIAL_LOOP_SERIAL0_NAME,
             0,                     // Does not depend on a lower level interface
             &cyg_io_serial_devio, 
             loop_serial_init, 
             loop_serial_lookup,     // Serial driver may need initializing
             &loop_serial_channel0
    );
#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL0

#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL1
DEVTAB_ENTRY(loop_serial_io1, 
             CYGDAT_IO_SERIAL_LOOP_SERIAL1_NAME,
             0,                     // Does not depend on a lower level interface
             &cyg_io_serial_devio, 
             loop_serial_init, 
             loop_serial_lookup,     // Serial driver may need initializing
             &loop_serial_channel1
    );
#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL1

//-------------------------------------------------------------------------

static bool
loop_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
{
//    loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;
 
    if (new_config != &chan->config) {
        chan->config = *new_config;
    }
    return true;
}

//-------------------------------------------------------------------------
// Function to initialize the device.  Called at bootstrap time.

bool loop_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
//    loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;

    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices

#ifndef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE    

    // Set up alarm for feeding data back into channels

    cyg_alarm_create( cyg_real_time_clock(),
                      alarm_handler,
                      0,
                      &alarm_handle,
                      &alarm_obj);

    cyg_alarm_initialize( alarm_handle, 1, 1 );
    
#endif
    
    loop_serial_config_port(chan, &chan->config, true);
    
    return true;
}

//-------------------------------------------------------------------------
// This routine is called when the device is "looked" up (i.e. attached)

static Cyg_ErrNo 
loop_serial_lookup(struct cyg_devtab_entry **tab, 
                  struct cyg_devtab_entry *sub_tab,
                  const char *name)
{
    serial_channel *chan = (serial_channel *)(*tab)->priv;
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    return ENOERR;
}

//-------------------------------------------------------------------------
// Return 'true' if character is sent to device

bool
loop_serial_putc(serial_channel *chan, unsigned char c)
{
    loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;

    struct fifo *f = loop_chan->write_fifo;

    if( f->num == FIFO_SIZE )
        return false;

    f->buf[f->tail] = c;
    f->num++;
    f->tail++;
    if( f->tail == sizeof(f->buf) )
        f->tail = 0;
    
    return true;
}

//-------------------------------------------------------------------------

unsigned char 
loop_serial_getc(serial_channel *chan)
{
    unsigned char c;
    loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;

    struct fifo *f = loop_chan->read_fifo;
    
    while( f->num == 0 )
        continue;

    c = f->buf[f->head];
    f->num--;
    f->head++;
    if( f->head == sizeof(f->buf) )
        f->head = 0;
    
    return c;
}

//-------------------------------------------------------------------------

static Cyg_ErrNo
loop_serial_set_config(serial_channel *chan, cyg_uint32 key,
                       const void *xbuf, cyg_uint32 *len)
{
    switch (key) {
    case CYG_IO_SET_CONFIG_SERIAL_INFO:
      {
        cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
        if ( *len < sizeof(cyg_serial_info_t) ) {
            return -EINVAL;
        }
        *len = sizeof(cyg_serial_info_t);
        if ( true != loop_serial_config_port(chan, config, false) )
            return -EINVAL;
      }
      break;
    default:
        return -EINVAL;
    }
    return ENOERR;
}

//-------------------------------------------------------------------------
// Enable the transmitter on the device

static void
loop_serial_start_xmit(serial_channel *chan)
{
#ifndef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE    
    loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;

    loop_chan->write_fifo->tx_enable = true;
    
    (chan->callbacks->xmt_char)(chan);
#endif    
}

//-------------------------------------------------------------------------
// Disable the transmitter on the device

static void 
loop_serial_stop_xmit(serial_channel *chan)
{
#ifndef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE    
    loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;

    loop_chan->write_fifo->tx_enable = false;
    
#endif    
}

//-------------------------------------------------------------------------

static void alarm_handler(cyg_handle_t alarm, cyg_addrword_t data)
{
    serial_channel *chan0 = &loop_serial_channel0;
    serial_channel *chan1 = &loop_serial_channel1;

    while( fifo0.num )
    {
        // Data ready for delivery to serial1

        struct fifo *f = &fifo0;
        char c;

        c = f->buf[f->head];
        f->num--;
        f->head++;
        if( f->head == sizeof(f->buf) )
            f->head = 0;

        (chan1->callbacks->rcv_char)(chan1, c);
        if( f->tx_enable )
            (chan0->callbacks->xmt_char)(chan0);        
    }

    while( fifo1.num )
    {
        // Data ready for delivery to serial0

        struct fifo *f = &fifo1;
        char c;

        c = f->buf[f->head];
        f->num--;
        f->head++;
        if( f->head == sizeof(f->buf) )
            f->head = 0;

        (chan0->callbacks->rcv_char)(chan0, c);
        if( f->tx_enable )
            (chan1->callbacks->xmt_char)(chan1);        
    }



}
    

#endif // CYGPKG_IO_SERIAL_LOOP

//-------------------------------------------------------------------------
// EOF loop.c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -