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

📄 iic_saa9730.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        addr = ((p_param->IICaddress) << 1) & 0xFE ; 

        /* Start IIC-write operation */
        rcode = IIC_SAA9730_add( &addr, IIC_TFR_BYTEATTR_START, IIC_WRITECMD) ;
        if (rcode != OK) return( rcode ) ;


        /* Stop IIC-write operation */
        rcode = IIC_SAA9730_add( &addr, IIC_TFR_BYTEATTR_STOP, IIC_WRITECMD) ;
        if (rcode != OK) return( rcode ) ;

        /* Flush any remaining data in command buffer */
        rcode = IIC_SAA9730_flush() ;
        return( rcode ) ;
    }

    if (p_param->command == IIC_CTRL_WRITE_READ)
    {
        /* WRITE-READ command: */

        /* Prepare IIC-write: set slave address and 'write' condition */
        addr = ((p_param->IICaddress) << 1) & 0xFE ; 

        /* Start IIC-write operation */
        rcode = IIC_SAA9730_add( &addr, IIC_TFR_BYTEATTR_START, IIC_WRITECMD) ;
        if (rcode != OK) return( rcode ) ;


        /* Continue IIC-write operation */
        wrd = p_param->data ;
        buffer = wrd->write_buffer ; 
        for (i = 0; i < wrd->write_length; i++)
        {
            rcode = IIC_SAA9730_add( buffer++, 
                                     IIC_TFR_BYTEATTR_CONT, 
                                     IIC_WRITECMD );
            if (rcode != OK) return( rcode ) ;
        }

        /* Prepare IIC-read: set slave address and 'read' condition */
        addr = ((p_param->IICaddress) << 1) | 0x01 ; 

        /* Start IIC-read operation */
        rcode = IIC_SAA9730_add( &addr, IIC_TFR_BYTEATTR_START, IIC_WRITECMD) ;
        if (rcode != OK) return( rcode ) ;

        /* Continue IIC-read operation */
        buffer = wrd->read_buffer ; 
        for (i = 1; i < wrd->read_length; i++)
        {
            rcode = IIC_SAA9730_add( buffer++, 
                                     IIC_TFR_BYTEATTR_CONT, 
                                     IIC_READCMD);
            if (rcode != OK) return( rcode ) ;
        }

        /* Complete IIC-read operation */
        rcode = IIC_SAA9730_add(buffer, IIC_TFR_BYTEATTR_STOP, IIC_READCMD);
        if (rcode != OK) return( rcode ) ;

        /* Flush any remaining data in command buffer */
        rcode = IIC_SAA9730_flush() ;
        return( rcode ) ;
    }

    return( rcode ) ;
}

/************************************************************************
 *      Local helper functions:
 ************************************************************************/


/************************************************************************
 *
 *                          IIC_SAA9730_reset
 *  Description :
 *  -------------
 *
 *  Reset command buffer
 *
 *
 *  Parameters :
 *  ------------
 *
 *  -
 *
 *  Return values :
 *  ---------------
 *
 *  -
 *
 *
 ************************************************************************/
static 
void IIC_SAA9730_reset( void )
{
    /* reset command buffer */
    buf.index    = 0;
    buf.attrib   = 0;
    buf.data[0]  = 0;
    buf.data[1]  = 0;
    buf.data[2]  = 0;
    buf.pread[0] = 0 ;
    buf.pread[1] = 0 ;
    buf.pread[2] = 0 ;
}


/************************************************************************
 *
 *                          IIC_SAA9730_check
 *  Description :
 *  -------------
 *
 *  Check status and control register for any detected errors.
 *
 *
 *  Parameters :
 *  ------------
 *
 *  -
 *
 *  Return values :
 *  ---------------
 *
 *  'OK' = 0x00:              IIC service completed successfully
 *  ERROR_IIC_ADDRESS_ERROR:  IIC address error
 *  ERROR_IIC_DATA_ERROR:     IIC data error
 *
 *
 ************************************************************************/
static 
INT32 IIC_SAA9730_check( void )
{
    UINT32 rcode = OK ;

    /* check for any error at all */
    if ( REGRD(saa9730base, IIC_STC, ERR) )
    {
        /* check for address phase error */
        if ( REGRD(saa9730base, IIC_STC, APERR) )
        {
           /* yes, it was a address phase error */
           rcode = ERROR_IIC_ADDRESS_ERROR ;
        }
        else
        {
           /* no, it was a data error */
           rcode = ERROR_IIC_DATA_ERROR ;
        }

        /* reset any error flag */
        REG(saa9730base, IIC_STC) = REGWRI(saa9730base, IIC_STC, ERR, 0) ;
    }
    return( rcode ) ;
}


/************************************************************************
 *
 *                          IIC_SAA9730_get_data
 *  Description :
 *  -------------
 *
 *  Get data from BYTE2, BYTE1 and BYTE0 of Transfer Register and
 *  save it in user allocated buffer space.
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  -
 *
 *
 *  Return values :
 *  ---------------
 *
 *  -
 *
 ************************************************************************/
static 
void IIC_SAA9730_get_data( void )
{
    int i;
    UINT32 iicdata ;

    /* get data from controller */
    iicdata = REG(saa9730base, IIC_TFR) ;

    /* save it in user allocated buffer space */
    for (i = 0; i < buf.index; i++)
    {
        if (buf.pread[i] != NULL)
        {
            *(buf.pread[i]) = (UINT8)(iicdata >> ((3-i)*8));
        }
    }
}


/************************************************************************
 *
 *                          IIC_SAA9730_flush
 *  Description :
 *  -------------
 *
 *  Flush out any command or data of command buffer into Transfer
 *  Register.
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  -
 *
 *  Return values :
 *  ---------------
 *
 *  'OK' = 0x00:              IIC service completed successfully
 *  ERROR_IIC_ADDRESS_ERROR:  IIC address error
 *  ERROR_IIC_DATA_ERROR:     IIC data error
 *  ERROR_IIC_TIMEOUT:        IIC service timed-out
 * 
 ************************************************************************/
static 
INT32 IIC_SAA9730_flush( void )
{
    int rcode = OK ;
    UINT32 iicdata ;

    /* check for any pending commands */
    if ( buf.index > 0 )
    {
        /* TFR-register: request 9730 to transmit max. 3 bytes */
        iicdata = ( (buf.data[0] << 24) | 
                    (buf.data[1] << 16) | 
                    (buf.data[2] <<  8) | 
                    (buf.attrib) ) ;

        REG(saa9730base, IIC_TFR) = iicdata ;

        rcode = IIC_SAA9730_wait() ;
        if (rcode == OK)
        {
            rcode = IIC_SAA9730_check() ;
            if (rcode == OK)
            {
               IIC_SAA9730_get_data() ;
            }
        }

        /* reset command buffer */
        IIC_SAA9730_reset() ;
    }
    return( rcode ) ;
}

/************************************************************************
 *
 *                          IIC_SAA9730_add
 *  Description :
 *  -------------
 *
 *  Add another data byte to command buffer and flush in case
 *  command buffer gets full.
 *  
 *
 *  Parameters :
 *  ------------
 *  'data':                   pointer for next data byte to add
 *  'attrib':                 either 'nop', 'start', 'cont', 'stop'
 *  'read':                   'true' by read, 'false' by 'write'.
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK' = 0x00:              IIC service completed successfully
 *  ERROR_IIC_ADDRESS_ERROR:  IIC address error
 *  ERROR_IIC_DATA_ERROR:     IIC data error
 *  ERROR_IIC_TIMEOUT:        IIC service timed-out
 *
 *
 ************************************************************************/
static 
INT32 IIC_SAA9730_add( UINT8 *data,
                       UINT8 attrib,
                       UINT8 read )
{
    /* check for read or write */
    if ( read == IIC_READCMD )
    {
        /* read command: save pointer for storing data */
        buf.data[buf.index]    = 0 ;
        buf.pread[buf.index++] = data ;
    }
    else
    {
        /* write command: store data */
        buf.data[buf.index]    = *data ;
        buf.pread[buf.index++] = 0 ;
    }

    /* set attribute for stored byte */
    buf.attrib |= ((attrib)&0x03) << (2*(4 - buf.index));


    /* check for buffer full, and flush */
    if (buf.index == 3)
    {
        return( IIC_SAA9730_flush() ) ;
    }
    return OK ;
}


/************************************************************************
 *
 *                          IIC_SAA9730_wait
 *  Description :
 *  -------------
 *  
 *  Await IIC-bus operation being completed
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  -
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK' = 0x00:              IIC service completed successfully
 *  'ERROR_IIC_TIMEOUT'       IIC service timed-out
 *
 *
 ************************************************************************/
static 
INT32 IIC_SAA9730_wait( void )
{
    UINT32 rc, first, latest, previous, accumulate, millisec ;

    accumulate = 0 ;

    /* get millisecond count */
    rc = SYSCON_read( SYSCON_BOARD_GET_MILLISEC_ID,
                      &first,
                      sizeof(first) ) ;
    previous = first ;
    millisec = IIC_TIMEOUT ;


    while( 1 )
    {
        if ( !REGRD(saa9730base, IIC_STC, BUSY) )
        {
            return OK ;
        }

        /* get millisecond count */
        rc = SYSCON_read( SYSCON_BOARD_GET_MILLISEC_ID,
                          &latest,
                          sizeof(latest) ) ;
        if ( latest >= previous )
        {
            /* counter still not wrapped */
            if ( (accumulate + (latest - first)) > millisec )
            {
                /* time-out */
                break ;
            }
        }
        else
        {
            /* counter did wrap */
            accumulate = accumulate + (previous - first) ;
            if ( (accumulate + latest) > millisec )
            {
                /* time-out */
                break ;
            }

            /* reset first */
            first = 0 ;
        }

        /* prepare next delta time */
        previous = latest ;
    }

    /* time-out */

    /* reset busy flag */
    REG(saa9730base, IIC_STC) = REGWRI(saa9730base, IIC_STC, BUSY, 0) ;
         
    /* reset any error flag */
    REG(saa9730base, IIC_STC) = REGWRI(saa9730base, IIC_STC, ERR, 0) ;

    return( ERROR_IIC_TIMEOUT ) ;
}

⌨️ 快捷键说明

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