📄 i2cmgr.c
字号:
if(RZKDEV_OPENED != pDCB->InUse)
return I2CERR_INVALID_OPERATION ;
if(I2C_BUS_BUSY == pDCB->InUse)
return I2CERR_BUSBUSY ;
else
{
RZKAcquireSemaphore(hSem_I2C,INFINITE_SUSPEND);
// mask = RZKDisablePreemption() ;
pDCB->InUse |= I2C_BUS_BUSY ;
/* If master
Send start condn
Send slave addr with write bit
Send start again
Send slave addr with read bit
read the data into the given buffer
Send stop condn
If slave
read data available in the Rx buffer
If no data is available block and wait for data to arrive and enable the Rx interrupt
*/
if(I2C_MASTER == i2cConfigParams.mode)
{
stat = I2CDev_SendStart() ;
if(stat<0)
{
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKReleaseSemaphore(hSem_I2C);
// RZKRestorePreemption(mask) ;
return stat ;
}
slvaddr |= I2CMODE_TRANSMIT ;
stat = I2CDev_TransmitDataByte(slvaddr) ;
if(stat<0)
{
I2CDev_SendStop() ;
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKReleaseSemaphore(hSem_I2C);
// RZKRestorePreemption(mask) ;
return stat ;
}
if(useSubAddr == RZK_TRUE)
{
switch(i2cConfigParams.addrLen)
{
case 3:
stat = I2CDev_TransmitDataByte(subAddr) ;
if(stat<0)
break ;
subAddr >>= 8 ;
case 2:
stat = I2CDev_TransmitDataByte(subAddr) ;
if(stat<0)
break ;
subAddr >>= 8 ;
case 1:
stat = I2CDev_TransmitDataByte(subAddr) ;
break ;
}
if(stat<0)
{
I2CDev_SendStop() ;
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKReleaseSemaphore(hSem_I2C);
// RZKRestorePreemption(mask) ;
return stat ;
}
}
stat = I2CDev_SendStart() ;
if(stat<0)
{
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKReleaseSemaphore(hSem_I2C);
// RZKRestorePreemption(mask) ;
return stat ;
}
slvaddr |= I2CMODE_RECEIVE ;
stat = I2CDev_TransmitDataByte(slvaddr) ;
if(stat<0)
{
I2CDev_SendStop() ;
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKReleaseSemaphore(hSem_I2C);
// RZKRestorePreemption(mask) ;
return stat ;
}
I2C_SetAAKClearIFlag(temp) ;
for(i=0; i<size; i++)
{
stat = I2CDev_ReceiveDataByte(buf++) ;
if(stat < 0)
{
I2CDev_SendStop() ;
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKReleaseSemaphore(hSem_I2C);
// RZKRestorePreemption(mask) ;
return stat ;
}
if(i<size-2)
{
I2C_SetAAKClearIFlag(temp) ;
}
else
{
I2C_ResetAAKClearIFlag() ;
I2CDev_ReceiveDataByte(buf++) ;
break ;
}
}
I2CDev_SendStop() ;
count = COUNT_DELAY ;
I2C_Delay(count) ;
}
else
{
if(size > rxCQ.avail)
size = rxAvail ;
I2C_SetAAKClearIFlag(temp) ;
for(i=0; i<size; i++)
{
*buf++ = CQ_OUT(&rxCQ) ;
}
}
}
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKReleaseSemaphore(hSem_I2C);
// RZKRestorePreemption(mask) ;
return size ;
}
DDF_STATUS_t I2CControl( RZK_DEVICE_CB_t *pDCB, RZK_DEV_BYTES_t uOperation, INT8 *addr1, INT8 *addr2 )
{
UINTRMASK intmask ;
/* change the slave address, UseSubAddr, Subaddr, speed
*/
if(RZKDEV_OPENED != pDCB->InUse)
return I2CERR_INVALID_OPERATION ;
if(I2C_BUS_BUSY == pDCB->InUse)
return I2CERR_BUSBUSY ;
else
{
intmask = RZKDisableInterrupts() ;
pDCB->InUse |= I2C_BUS_BUSY ;
RZKEnableInterrupts(intmask) ;
}
switch((UINT)uOperation)
{
case I2C_SET_SLAVE_ADDR:
i2cConfigParams.currSlaveAddr = *addr1 ;
break ;
case I2C_SUBADDR_USED:
i2cConfigParams.useSubAddr = RZK_TRUE ;
i2cConfigParams.subAddr = *((UINT16 *)addr1) ;
break ;
case I2C_SUBADDR_NOT_USED:
i2cConfigParams.useSubAddr = RZK_FALSE ;
i2cConfigParams.subAddr = 0 ;
break ;
case I2C_SUBADDR_LEN :
i2cConfigParams.addrLen = 0 ;
i2cConfigParams.addrLen = *addr1 ;
break ;
case I2C_SET_SPEED:
i2cConfigParams.speed = *addr1 ;
I2C_CCR = i2cConfigParams.speed ;
break ;
}
intmask = RZKDisableInterrupts() ;
pDCB->InUse &= ~I2C_BUS_BUSY ;
RZKEnableInterrupts(intmask) ;
return I2CERR_SUCCESS ;
}
UINT8* pBuff = i2cRxBuff ;
void I2cInterruptTask(void)
{
UINT8 i2cStatus ;
INT8 ch ;
UINTRMASK intmask, intrmask ;
// RZK_STATE_t mask ; //Commented during IAR Porting
UINT16 temp ;
/* look for the kind of interrupt
*Validate the slave address wrt own address
*Send ack
*If slave read
*Read the incoming data into a circular buffer
*If a thread is pending on IO by calling I2C read then resume the thd
*If slave write
*
*
*/
while(1)
{
i2cStatus = I2C_SR ;
switch(i2cStatus)
{
case I2CSTAT_SLAWRXD_ACKTXD:
case I2CSTAT_SLDATARXD_ACKTXD:
{
/* receive the data into Rx circular buffer.
buffer will not check for full condition
and keep receiving the data if the
buffer is not updated with fresh data.
*/
I2CDev_ReceiveDataByte(&ch) ;
I2C_SetAAKClearIFlag(temp) ;
intrmask = RZKDisableInterrupts() ;
CQ_IN(&rxCQ, ch) ;
RZKEnableInterrupts(intrmask) ;
}
break ;
case I2CSTAT_SLARRXD_ACKTXD:
case I2CSTAT_SLDATATXD_ACKRXD:
{
/* Transmit the data present in the Tx buffer
Circular Buffer will not check for empty condn
and keep transmitting the same data if the
buffer is not updated with fresh data.
*/
intrmask = RZKDisableInterrupts() ;
ch = CQ_OUT(&txCQ) ;
intrmask = RZKDisableInterrupts() ;
I2CDev_TransmitDataByte(ch) ;
}
break ;
case I2CSTAT_SLDATARXD_NACKTXD:
I2C_SetAAKClearIFlag(temp) ;
break ;
case I2CSTAT_SLSTOPREPSTART_RXD:
I2C_SetAAKClearIFlag(temp) ;
break ;
case I2CSTAT_SLDATARXD_ACKNRXD:
I2C_SetAAKClearIFlag(temp) ;
break ;
case I2CSTAT_SLDATALASTTXD_ACKRXD:
I2C_SetAAKClearIFlag(temp) ;
break ;
case I2CSTAT_NORELEVANT_STATUS:
I2C_SetAAKClearIFlag(temp) ;
break ;
default :
printf("condition not handled\n") ;
break ;
}
intmask = RZKDisableInterrupts() ;
/* Enabling the I2C interrupts */
I2C_CTL |= I2CMASK_SET_INT ;
RZKSuspendInterruptThread() ;
RZKEnableInterrupts(intmask) ;
}
}
/*****************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -