📄 iic_saa9730.c
字号:
/* set default error, if command not recognized */ rcode = ERROR_IIC_UNKNOWN_COMMAND ; if (p_param->command == IIC_CTRL_TEST) { /* TEST 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 ) ; /* 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 ( REG(saa9730base, IIC_STC) & IIC_STC_ERR_SET ) { /* check for address phase error */ if ( REG(saa9730base, IIC_STC) & IIC_STC_APERR_SET ) { /* 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) &= ~IIC_STC_ERR_SET; } 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 ( !(REG(saa9730base, IIC_STC) & IIC_STC_BUSY_SET) ) { 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 and any error flag */ REG(saa9730base, IIC_STC) &= ~(IIC_STC_BUSY_SET | IIC_STC_ERR_SET); return( ERROR_IIC_TIMEOUT ) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -