- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I try to get the I2C interface working correct with DMA. So far so good the point is, I can send and receive each one time with the function "CyU3PI2cSendCommand". The Callback with the event "CY_U3P_I2C_EVENT_RX_DONE" and "CY_U3P_I2C_EVENT_TX_DONE" occurs in each case too. I think it needs anything to be done at this time but I do not know what! I tried some DMA functions:
- CyU3PDmaChannelAbort
- CyU3PDmaChannelResume
- CyU3PDmaChannelReset
The second send or receive does each time nothing. The I2cSendCommand call return SUCCESS but nothing happened.
How can I use the I2C module more than one time in DMA mode?
C - Code:
CyU3PErrorCode_t IS_I2cInit(void)
{
CyU3PErrorCode_t status = CY_U3P_SUCCESS;
CyU3PI2cConfig_t config;
status = CyU3PI2cInit();
if(status != CY_U3P_SUCCESS)
{
return status;
}
status = IS_I2cCreateDmaChannel();
if(status != CY_U3P_SUCCESS)
{
return status;
}
glWriteBuffer.buffer = &glWriteData[0];
glWriteBuffer.count = 0;
glWriteBuffer.size = I2C_DMA_BUF_SIZE;
glWriteBuffer.status = NULL;
glReadBuffer.buffer = &glReadData[0];
glReadBuffer.count = 0;
glReadBuffer.size = I2C_DMA_BUF_SIZE;
glReadBuffer.status = NULL;
glI2cLock = CyFalse;
config.bitRate = 400000; // 400 kHz
config.isDma = CyTrue; // Register transfer mode
config.busTimeout = 0xFFFFFFFFU; // no timeout
config.dmaTimeout = 0xFFFF; // no timeout
status = CyU3PI2cSetConfig(&config, &IS_I2cIR);
if(status != CY_U3P_SUCCESS)
{
return status;
}
return status;
}
void IS_I2cIR(CyU3PI2cEvt_t evt, CyU3PI2cError_t error)
{
CyU3PErrorCode_t status = CY_U3P_SUCCESS;
switch(evt)
{
case CY_U3P_I2C_EVENT_RX_DONE:
if(glI2cLock == CyTrue)
{
status = CyU3PDmaChannelAbort(&glDmaChannelHandleI2c);
glI2cLock = CyFalse;
}
else
{
IS_I2cErrorEvent(error);
}
break;
case CY_U3P_I2C_EVENT_TX_DONE:
if(glI2cLock == CyTrue)
{
status = CyU3PDmaChannelAbort(&glDmaChannelHandleI2c);
glI2cLock = CyFalse;
}
else
{
IS_I2cErrorEvent(error);
}
break;
case CY_U3P_I2C_EVENT_TIMEOUT:
break;
case CY_U3P_I2C_EVENT_LOST_ARBITRATION:
break;
case CY_U3P_I2C_EVENT_ERROR:
IS_I2cErrorEvent(error);
break;
default:
break;
}
}
CyU3PErrorCode_t IS_I2cWrite(uint8_t dvcAdr, uint8_t sizeAdr, uint8_t *pAdr, uint8_t sizeData, uint8_t *pData)
{
while(glI2cLock==CyTrue);
CyU3PErrorCode_t status = CY_U3P_SUCCESS;
glWriteBuffer.buffer = pData;
glWriteBuffer.count = sizeData;
status = CyU3PDmaChannelSetupSendBuffer(&glDmaChannelHandleI2c, &glWriteBuffer);
//if(status == CY_U3P_SUCCESS)
{
glI2cLock = CyTrue;
status = IS_I2cCommunicate(CyFalse, dvcAdr, sizeAdr, pAdr, sizeData, pData);
}
return status;
}
CyU3PErrorCode_t IS_I2cRead(uint8_t dvcAdr, uint8_t sizeAdr, uint8_t *pAdr, uint8_t sizeData, uint8_t *pData)
{
while(glI2cLock==CyTrue);
CyU3PErrorCode_t status = CY_U3P_SUCCESS;
glReadBuffer.buffer = pData;
glReadBuffer.count = sizeData;
status = CyU3PDmaChannelSetupRecvBuffer(&glDmaChannelHandleI2c, &glReadBuffer);
//if(status == CY_U3P_SUCCESS)
{
glI2cLock = CyTrue;
status = IS_I2cCommunicate(CyTrue, dvcAdr, sizeAdr, pAdr, sizeData, pData);
}
return status;
}
CyU3PErrorCode_t IS_I2cCommunicate(CyBool_t read, uint8_t dvcAdr, uint8_t sizeAdr, uint8_t *pAdr, uint8_t sizeData, uint8_t *pData)
{
CyU3PErrorCode_t status = CY_U3P_SUCCESS;
CyU3PI2cPreamble_t preamble;
uint8_t CntBytesPreamble = 0;
uint8_t LengthAdr = 0;
uint8_t dvcAdrWrite = dvcAdr & 0xFE;
uint8_t dvcAdrRead = dvcAdr | 0x01;
preamble.ctrlMask = 0;
preamble.length = 0;
if(sizeAdr > 0)
{
preamble.buffer[0] = dvcAdrWrite;
CntBytesPreamble++;
}
for(LengthAdr = 0; LengthAdr < sizeAdr; LengthAdr++)
{
preamble.buffer[LengthAdr+1] = pAdr[LengthAdr];
CntBytesPreamble++;
}
if(read == CyTrue)
{
if(sizeAdr > 0)
{
preamble.buffer[++LengthAdr] = dvcAdrRead;
preamble.length = (++CntBytesPreamble);
preamble.ctrlMask = 0x01 << (CntBytesPreamble-2);
}
}
else
{
preamble.length = CntBytesPreamble;
preamble.ctrlMask = 0x00;
}
//status = CyU3PI2cSetBlockXfer(sizeData);
status = CyU3PI2cSendCommand(&preamble, sizeData, read);
return status;
}
CyU3PErrorCode_t IS_I2cCreateDmaChannel(void)
{
CyU3PDmaChannelConfig_t dmaI2cConfig;
CyU3PErrorCode_t status = CY_U3P_SUCCESS;
/* Create a DMA MANUAL Channel between two sockets of the U port */
dmaI2cConfig.size = I2C_DMA_BUF_SIZE;
dmaI2cConfig.count = I2C_DMA_BUF_COUNT;
dmaI2cConfig.prodSckId = CY_U3P_LPP_SOCKET_I2C_PROD;
dmaI2cConfig.consSckId = CY_U3P_LPP_SOCKET_I2C_CONS;
dmaI2cConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaI2cConfig.notification = CY_U3P_DMA_CB_XFER_CPLT;
dmaI2cConfig.cb = Is_I2cDmaCallback;
dmaI2cConfig.prodHeader = 0;
dmaI2cConfig.prodFooter = 0;
dmaI2cConfig.consHeader = 0;
dmaI2cConfig.prodAvailCount = 0;
/* Create the channel */
status = CyU3PDmaChannelCreate(&glDmaChannelHandleI2c, CY_U3P_DMA_TYPE_AUTO, &dmaI2cConfig);
return status;
}