📄 iic_saa9730.c
字号:
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 + -