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

📄 h8s_sci_serial.c

📁 ecos移植到R8H系列的源码。源码包来自http://www.cetoni.de/develop/develop_ecosh8s_en.html
💻 C
📖 第 1 页 / 共 2 页
字号:
                                 0,                                      // no ISR for er interrupts
                                 &ph8s_chan->serial_er_interrupt_handle,
                                 &ph8s_chan->serial_er_interrupt);

        cyg_drv_interrupt_attach(ph8s_chan->serial_er_interrupt_handle);
        //
        // This unmasks both interrupt sources.
        //
        cyg_drv_interrupt_unmask(ph8s_chan->rx_int_num);
    } // End of if (chan->in_cbuf.len != 0) 
    ret = h8s_serial_config_port(pchan, &pchan->config, true);
    return ret;
}

 
//==========================================================================
//                                SERIAL LOOK UP
// DESCRIPTION:
//     This routine is called when the device is "looked" up (i.e. attached)
//
// ARGUMENTS:
//     '**tab'    Points to pointer to device tab entry of this driver        
//
// RETURNS:
//     ENOERR on success
//==========================================================================
static Cyg_ErrNo h8s_serial_lookup(
    struct cyg_devtab_entry **tab, 
    struct cyg_devtab_entry  *sub_tab,
    const  char              *name)
{
    serial_channel *pchan = (serial_channel *)(*tab)->priv;
     
    //
    // Really only required for interrupt driven devices
    //
    (pchan->callbacks->serial_init)(pchan);
    
    return ENOERR;
}


//==========================================================================
//                       PUT CHAR TO DEVICE OUTPUT BUFFER
// DESCRIPTION:
//     Send a character to the device output buffer.
//
// ARGUMENTS:
//     '*pchan'    Points to serial channel
//     'c'         Char to bes sent      
//
// RETURNS:
//     'true' if character is sent to device
//==========================================================================
static bool h8s_serial_putc(serial_channel *pchan, unsigned char c)
{
    cyg_uint8     _ssr;
    h8s_sci_info *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;


    HAL_READ_UINT8(ph8s_chan->ctrl_base + SCI_SCSSR, _ssr);
    //
    // Check if transmit buffer is empty - that means it
    //
    if (_ssr & CYGARC_REG_SCSSR_TDRE) 
    {
        //
        // Transmit buffer is empty
        //
        HAL_WRITE_UINT8(ph8s_chan->ctrl_base + SCI_SCTDR, c);
        //
        // Clear empty flag.
        //
        HAL_WRITE_UINT8(ph8s_chan->ctrl_base + SCI_SCSSR, 
                        CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_TDRE);
        return true;
    } 
    else 
    {
        //
        // No space
        //
        return false;
    }
}

 
//==========================================================================
//                       GET CHAR FROM DEVICE INPUT BUFFER
// DESCRIPTION:
//     Fetch a character from the device input buffer, waiting if necessary
//
// ARGUMENTS:
//     '*pchan'    Points to serial channel    
//
// RETURNS:
//     Recveived character
//==========================================================================
static unsigned char h8s_serial_getc(serial_channel *pchan)
{
    h8s_sci_info *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;
    unsigned char c;
    cyg_uint8     _ssr;

    //
    // Wait until we receive one character
    //
    do 
    {
        HAL_READ_UINT8(ph8s_chan->ctrl_base + SCI_SCSSR, _ssr);
        //
        // Check if ORER, FER or PER received - we have to clear it
        //
        if(_ssr & CYGARC_REG_SCSSR_RCVERR)
        {   
            _ssr &=~CYGARC_REG_SCSSR_RCVERR;
            HAL_WRITE_UINT8(ph8s_chan->ctrl_base + SCI_SCSSR, _ssr);   
        }
    } 
    while ((_ssr & CYGARC_REG_SCSSR_RDRF) == 0);

    HAL_READ_UINT8(ph8s_chan->ctrl_base + SCI_SCRDR, c);
    //
    // Clear buffer full flag.
    //
    HAL_WRITE_UINT8(ph8s_chan->ctrl_base + SCI_SCSSR, 
                    CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);

    return c;
}


//==========================================================================
//                       SET UP DEVICE CHARACTERISTICS
// DESCRIPTION:
//     Set up the device characteristics; baud rate, etc.
//
// ARGUMENTS:
//     '*pchan'    Points to serial channel   
//     'key'       Configuration key value
//     '*pxbuf     Points to xbuf
//     '*plen'     Points to lenof xbuf
//
// RETURNS:
//     'ENOERR'    on success
//     '-EINVAL'   on error
//==========================================================================
static Cyg_ErrNo h8s_serial_set_config(
    serial_channel *pchan, 
    cyg_uint32      key,
    const void     *pxbuf, 
    cyg_uint32     *plen)
{   
    switch (key) 
    {
        case CYG_IO_SET_CONFIG_SERIAL_INFO:
             {
                 cyg_serial_info_t *pconfig = (cyg_serial_info_t *)pxbuf;
                 if (*plen < sizeof(cyg_serial_info_t)) 
                 {
                     return -EINVAL;
                 }
                 *plen = sizeof(cyg_serial_info_t);
                 if (true != h8s_serial_config_port(pchan, pconfig, false))
                 {
                     return -EINVAL;
                 }
             }
             break;
             
        default:
             return -EINVAL;
    } // End of switch (key)
    
    return ENOERR;
}


//==========================================================================
//                              ENABLE TRANSMITTER
// DESCRIPTION:
//     In interrupt mode, turn on the transmitter and allow for transmit 
//     interrupts.
//
// ARGUMENTS:
//     '*pchan'    Points to serial channel    
//==========================================================================
static void h8s_serial_start_xmit(serial_channel *pchan)
{
    h8s_sci_info   *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;

    
    ph8s_chan->tx_enabled = true;
    //
    // Mask the interrupts (all sources of the unit) while changing
    // the CR since a rx interrupt in the middle of this would result
    // in a bad CR state. cyg_drv_interrupt_umask is interrupt save - 
    // so there is no need to mask any other interrupts here
    //
    cyg_drv_interrupt_unmask(ph8s_chan->tx_int_num);
}


//==========================================================================
//                              DISABLE TRANSMITTER
// DESCRIPTION:
//     In interrupt mode, turn off the transmitter.
//
// ARGUMENTS:
//     '*pchan'    Points to serial channel    
//==========================================================================
static void h8s_serial_stop_xmit(serial_channel *pchan)
{
    h8s_sci_info *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;
    

    ph8s_chan->tx_enabled = false;
    //
    // Mask the interrupts (all sources of the unit) while changing
    // the CR since a rx interrupt in the middle of this would result
    // in a bad CR state. cyg_drv_interrupt_umask is interrupt save - 
    // so there is no need to mask any other interrupt here
    //
    // disable transmit interrupts
    //
    cyg_drv_interrupt_mask(ph8s_chan->tx_int_num);
}


//==========================================================================
//                                   TX ISR
// DESCRIPTION:
//     Serial I/O - tx interrupt handler (ISR). This handler will do only
//     the minimum required low level stuff an then posts a DSR for 
//     further processing.
//
// ARGUMENTS:
//     'vector'    Interrupt vector
//     'pdata'     Points to interrupt data  
//==========================================================================
static cyg_uint32 h8s_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t pdata)
{
    serial_channel *pchan     = (serial_channel *)pdata;
    h8s_sci_info   *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;


#if DEBUG & 1    
    int_cnt_tx_isr++; 
#endif
    //
    // interrupts are disabled here in the ISR so we can call 
    // cyg_drv_interrupt_mask_intunsafe. We do not acknowledge the interrupt 
    // because the hardware independent driver calls putc later and this will
    // clear the TDRE flag.
    //
    cyg_drv_interrupt_mask_intunsafe(ph8s_chan->tx_int_num);
    //
    // post DSR
    //
    return CYG_ISR_CALL_DSR | CYG_ISR_HANDLED;  
}


//==========================================================================
//                                   TX DSR
// DESCRIPTION:
//     Serial I/O - high level tx interrupt handler (DSR)
//
// ARGUMENTS:
//     'vector'    Interrupt vector
//     'count'    
//     'pdata'     Points to interrupt data  
//==========================================================================
static void h8s_serial_tx_DSR(
    cyg_vector_t   vector, 
    cyg_ucount32   count, 
    cyg_addrword_t pdata)
{
    serial_channel *pchan     = (serial_channel *)pdata;
    h8s_sci_info   *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;

#if DEBUG & 1
    int_cnt_tx_dsr++;
#endif

    (pchan->callbacks->xmt_char)(pchan);
    //
    // if interrupts are enabled for this channel then turn them on now
    //
    if (ph8s_chan->tx_enabled) 
    {
        //
        // unmask tx interrupts - because in DSR interrupts are enabled we
        // have to use cyg_drv_interrupt_unmask because it is interrupt safe
        //
        cyg_drv_interrupt_unmask(ph8s_chan->tx_int_num);
    }
}


//==========================================================================
//                                   RX ISR
// DESCRIPTION:
//     Serial I/O - low level RX interrupt handler (ISR). This ISR handles
//     only the minimum low level stuff and posts a DSR for further 
//     processing
//
// ARGUMENTS:
//     'vector'    Interrupt vector
//     'pdata'     Points to interrupt data  
//==========================================================================
static cyg_uint32 h8s_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t pdata)
{
    serial_channel *pchan     = (serial_channel *)pdata;
    h8s_sci_info   *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;

#if DEBUG & 1
    int_cnt_rx_isr++;
#endif
    //
    // mask out rx interrupts until the dsr execution completes and then
    // acknowledge the interrrupt (this will clear the RDRF flag)
    //
    cyg_drv_interrupt_mask_intunsafe(ph8s_chan->rx_int_num);
    //
    // Cause DSR to run
    //
    return  CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;  
}



//==========================================================================
//                                   RX DSR
// DESCRIPTION:
//     Serial I/O - high level rx interrupt handler (DSR)
//
// ARGUMENTS:
//     'vector'    Interrupt vector
//     'count'    
//     'pdata'     Points to interrupt data  
//==========================================================================
static void h8s_serial_rx_DSR(
    cyg_vector_t   vector, 
    cyg_ucount32   count, 
    cyg_addrword_t pdata)
{
    serial_channel *pchan     = (serial_channel *)pdata;
    h8s_sci_info   *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;
    cyg_uint8       _c;


#if DEBUG & 1
    int_cnt_rx_dsr++;
#endif
    //
    // read received char, acknowledge the interrupt and post 
    // received char to high level serial driver
    //
    HAL_READ_UINT8(ph8s_chan->ctrl_base + SCI_SCRDR, _c);
    cyg_drv_interrupt_acknowledge(ph8s_chan->rx_int_num);
    (pchan->callbacks->rcv_char)(pchan, _c);  
    //
    // Now it is save to unmask interrupts again
    //
    cyg_drv_interrupt_unmask(ph8s_chan->rx_int_num);
}


//==========================================================================
//                                   ERROR ISR
// DESCRIPTION:
//     Serial I/O - low level error interrupt handler (ISR)
//
// ARGUMENTS:
//     'vector'    Interrupt vector
//     'pdata'     Points to interrupt data  
//==========================================================================
static cyg_uint32 h8s_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t pdata)
{
    serial_channel *pchan     = (serial_channel *)pdata;
    h8s_sci_info   *ph8s_chan = (h8s_sci_info *)pchan->dev_priv;
    
    
    cyg_drv_interrupt_acknowledge(ph8s_chan->er_int_num);
    //
    // We do not use a DSR for failures
    //
    return CYG_ISR_HANDLED;            
}


//---------------------------------------------------------------------------
#endif // #ifdef CYGDAT_IO_SERIAL_H8S_SCI_INL

⌨️ 快捷键说明

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