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

📄 h8s_sci.c

📁 ecos移植到R8H系列的源码。源码包来自http://www.cetoni.de/develop/develop_ecosh8s_en.html
💻 C
📖 第 1 页 / 共 2 页
字号:
}



//=============================================================================
//                          READ BUFFER OF CHARACTERS
///
///  Read a number of chars from serial channel.
///  Reads __len number of charaters from serail channel and stores them into
///  the buffer __buf.
///
///  \param  __ch_data  Pointer to channel configuration data
///  \param  __buf      Receive buffer 
///  \param  __len      Number of chars to be received.
//=============================================================================
void hal_sci_read(void      *__ch_data, 
                  cyg_uint8 *__buf, 
                  cyg_uint32 __len)
{
    CYGARC_HAL_SAVE_GP();
    //
    // Read a number of chars from SCI until __len ist counted down
    // to zero
    //
    while(__len-- > 0)
    {
        *__buf++ = hal_sci_getc(__ch_data);
    }

    CYGARC_HAL_RESTORE_GP();
}


//=============================================================================
//                       READ CHARACTER WITH TIMEOUT
///
///  Reads a character from serial channel with timeout.
///
///  \param    __ch_data   Pointer to channel configuration data
///  \param    ch          Stores received character
///
///  \retval  TRUE if character was received successfully
//=============================================================================
cyg_bool hal_sci_getc_timeout(void *__ch_data, cyg_uint8 *ch)
{
    channel_data_t *chan = (channel_data_t*)__ch_data;
    int            delay_count;
    cyg_bool       res;


    CYGARC_HAL_SAVE_GP();

    delay_count = chan->msec_timeout * 20; // delay in .1 ms steps 
    //
    // Loop until we received a char or until time is over
    //
    while (1)
    {
        res = hal_sci_getc_nonblock(__ch_data, ch);
        if (res || (0 == delay_count--))
        {
            break;
        }
        
        CYGACC_CALL_IF_DELAY_US(50);
    }

    CYGARC_HAL_RESTORE_GP();
    return res;
}


//=============================================================================
//                          CONTROL SCI DEVICE
///
///    IOCTL-like function for controlling serial device.
///    Its possible to enable, disable interrupts here, change the baudrate
///    set the timeout value and query the interrup vector
///
///    \param  __ch_data  Points to channel configuratin data. The following
///                       symbolic constants should be used
///                       - __COMMCTL_IRQ_ENABLE     
///                       - __COMMCTL_IRQ_DISABLE    
///                       - __COMMCTL_DBG_ISR_VECTOR
///                       - __COMMCTL_SET_TIMEOUT
///                       - __COMMCTL_SETBAUD
///                       - __COMMCTL_GETBAUD
///    \param  __func     I/O control code
///     
///    \return   Control code dependent value
//=============================================================================
int hal_sci_control(void *__ch_data, __comm_control_cmd_t __func, ...)
{
    channel_data_t *chan      = (channel_data_t*)__ch_data;
    cyg_uint8       scr;
    int             ret       = 0;
    
    
    CYGARC_HAL_SAVE_GP();
    //
    // decide what we have to do according to the control command
    //
    switch (__func) 
    {
        //
        // Enable receive interrupts
        //
        case __COMMCTL_IRQ_ENABLE:
             HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
             scr |= CYGARC_REG_SCSCR_RIE;
             HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
             break;
        //
        // disable receive interrupts
        //
        case __COMMCTL_IRQ_DISABLE:
             HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
             scr &= ~CYGARC_REG_SCSCR_RIE;
             HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
             break;
        //
        // query isr vector of channel
        //
        case __COMMCTL_DBG_ISR_VECTOR:
             ret = chan->isr_vector;
             break;
        //
        // set new timeout and return the old one
        //
        case __COMMCTL_SET_TIMEOUT:
             {
                 va_list ap;

                 va_start(ap, __func);

                 ret = chan->msec_timeout;
                 chan->msec_timeout = va_arg(ap, cyg_uint32);

                 va_end(ap);
             } 
             break;
        //
        // set new baudrate for comm channel
        // 
        case __COMMCTL_SETBAUD:
             {
                cyg_uint32 baud_rate;
                cyg_uint8  tmp;
                va_list    ap;
                //
                // get baud rate from variable argument list
                //
                va_start(ap, __func);
                baud_rate = va_arg(ap, cyg_uint32);
                va_end(ap);
                //
                // disable sci interrupts while changing the hardware
                //
                HAL_READ_UINT8(chan->base + _REG_SCSCR, scr);
                tmp = scr;
                tmp = scr & ~(CYGARC_REG_SCSCR_TIE 
                            | CYGARC_REG_SCSCR_RIE
                            | CYGARC_REG_SCSCR_MPIE
                            | CYGARC_REG_SCSCR_TEIE);
                HAL_WRITE_UINT8(chan->base + _REG_SCSCR, tmp);
                //
                // Now set new baud rate - we have to set BRR and CKS in SCSMR
                //
                HAL_READ_UINT8(chan->base + _REG_SCSMR, tmp);                          
                tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK;
                tmp |= CYGARC_SCBRR_CKSx(baud_rate);
                HAL_WRITE_UINT8(chan->base + _REG_SCSMR, tmp);
                HAL_WRITE_UINT8(chan->base + _REG_SCBRR, CYGARC_SCBRR_N(baud_rate));
                //
                // now restore old scr register settings before disabling interrupts
                //
                HAL_WRITE_UINT8(chan->base + _REG_SCSCR, scr);
             } 
             break; // End of case __COMMCTL_SETBAUD: 
        //
        // Query baud rate
        //
        case __COMMCTL_GETBAUD:
             break; 
        //
        //
        //  
        default:
             ; // do nothing
    } // End of switch (__func) 

    CYGARC_HAL_RESTORE_GP();
    return ret;
}


//=============================================================================
//                          INTERRUPT HANDLER
///
///   Interrupt service routine for serial channel.
///   This interrupt handler, called from the spurious interrupt vector, 
///   is specifically for dealing with Ctrl-C interrupts from GDB. When called 
///   this function does the following: 
///        -# Check for an incoming character. The code here is very similar 
///           to that in cyg_hal_plf_sci_getc_nonblock(). 
///        -# Read the character and call cyg_hal_is_break(). 
///        -# if result is true, set *__ctrlc to 1. 
///        -# Return CYG_ISR_HANDLED. 
///
///   \param  __ch_data  Points to channel configuration data 
///   \param  __ctrlc    Stores CTRL C information 
///   \param  __vector   Interrupt vector number of interrupt wich called this ISR
///   \param  __data     Interrupt data passed to ISR from kernel
///        
///   \retval CYG_ISR_HANDLED
//=============================================================================
int hal_sci_isr(void         *__ch_data, 
                int          *__ctrlc, 
                CYG_ADDRWORD  __vector, 
                CYG_ADDRWORD  __data)
{
    cyg_uint8  c; 
    cyg_uint8  sr;
    cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
    int        res  = 0;


    CYGARC_HAL_SAVE_GP();

    *__ctrlc = 0;
    HAL_READ_UINT8(base + _REG_SCSSR, sr);
    if (sr & CYGARC_REG_SCSSR_ORER) 
    {
        //
        // Serial RX overrun. Clear error and hope protocol recovers.
        //
        HAL_WRITE_UINT8(base+_REG_SCSSR, 
                        CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_ORER);
        res = CYG_ISR_HANDLED;
    } 
    else if (sr & CYGARC_REG_SCSSR_RDRF) 
    {
        
        HAL_READ_UINT8(base+_REG_SCRDR, c);     // Received character
        HAL_WRITE_UINT8(base+_REG_SCSSR,        // Clear buffer full flag.
                        CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);

        if(cyg_hal_is_break(&c, 1 ))
        {
            *__ctrlc = 1;
        }

        res = CYG_ISR_HANDLED;
    }

    CYGARC_HAL_RESTORE_GP();
    return res;
}
#endif // End of #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG

//-----------------------------------------------------------------------------
// end of sci.c

⌨️ 快捷键说明

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