HI,all
I am using the I2C peripheral with DMA.
It seems that the system cannot work well.
Hardware: CC3200 LP rev 4.1
Software: SDK 1.1.0,FreeRTOS ,PMF (Power management framework)
I2C Pin: PIN_05, PIN_17.
I have tried to communicate with the on board sensor TMP006 and BMA22.
I can read/write the TMP006 register.
However, I have to do a "dummy read "first.
I can not read/write with BMA22 register.
Here is my code
Init the peripheral
void i2c_master_init_os() { osi_LockObjCreate(&lock_i2cTrans); osi_SyncObjCreate(&signal_i2cDone); osi_SyncObjCreate(&signal_i2cReadDone); } void i2c_master_init() { // // Configure I2C Master // MAP_I2CMasterInitExpClk(I2CA0_BASE,80000000,true); MAP_I2CIntRegister(I2CA0_BASE,I2CIntHandler); MAP_I2CMasterIntClearEx(I2CA0_BASE,0xFFFF); MAP_I2CMasterIntEnableEx(I2CA0_BASE,I2C_MASTER_INT_STOP|I2C_MASTER_INT_RX_DMA_DONE); MAP_I2CRxFIFOConfigSet(I2CA0_BASE,I2C_FIFO_CFG_RX_MASTER_DMA| I2C_FIFO_CFG_RX_TRIG_1); MAP_I2CTxFIFOConfigSet(I2CA0_BASE,I2C_FIFO_CFG_TX_MASTER_DMA| I2C_FIFO_CFG_TX_TRIG_1); /*MAP_uDMAChannelAssign(UDMA_CH25_I2CA0_RX); MAP_uDMAChannelAssign(UDMA_CH26_I2CA0_TX);*/ UDMAChannelSelect(UDMA_CH25_I2CA0_RX,NULL); UDMAChannelSelect(UDMA_CH26_I2CA0_TX,NULL); }
The read/write api.The problem is here: The RX FIFO is always not empty after "I2C_MASTER_INT_RX_DMA_DONE"
int I2C_Transfer( unsigned char ucDevAddr, unsigned char *ucWriteBuffer, unsigned char *ucReadBuffer, unsigned long ulWriteSize, unsigned long ulReadSize) { u8 rdData; if(ulReadSize==0 && ulWriteSize==0) return -1; if(ulWriteSize>256 || ulReadSize>256) return -1; osi_LockObjLock(&lock_i2cTrans,OSI_WAIT_FOREVER); /*UART_PRINT("Err:%x\r\n",MAP_I2CFIFOStatus (I2CA0_BASE)); while(MAP_I2CFIFODataGetNonBlocking (I2CA0_BASE,&rdData)>0) { UART_PRINT("%02x ",rdData); } UART_PRINT("\r\nErr:%x\r\n",MAP_I2CFIFOStatus (I2CA0_BASE));*/ if(ulWriteSize!=0) { osi_SyncObjClear(&signal_i2cDone); //i2c dma tx UDMASetupTransfer(UDMA_CH26_I2CA0_TX, UDMA_MODE_BASIC, ulWriteSize, UDMA_SIZE_8, UDMA_ARB_1, ucWriteBuffer, UDMA_SRC_INC_8, (u8 *)0x40020F00, UDMA_DST_INC_NONE); MAP_I2CMasterSlaveAddrSet(I2CA0_BASE,ucDevAddr,false); MAP_I2CMasterBurstLengthSet(I2CA0_BASE,ulWriteSize); MAP_I2CMasterIntClear(I2CA0_BASE); UDMAStartTransfer(UDMA_CH26_I2CA0_TX); MAP_I2CMasterControl(I2CA0_BASE,I2C_MASTER_CMD_FIFO_BURST_SEND_START| I2C_MASTER_CMD_FIFO_BURST_SEND_ERROR_STOP); osi_SyncObjWait(&signal_i2cDone,OSI_WAIT_FOREVER); Message("Send done!\r\n"); } UART_PRINT("Err:%x\r\n",MAP_I2CFIFOStatus (I2CA0_BASE)); if(ulReadSize!=0) { osi_SyncObjClear(&signal_i2cReadDone); osi_SyncObjClear(&signal_i2cDone); memset(ucReadBuffer,0,ulReadSize); readDone=0; //i2c dma rx UDMASetupTransfer(UDMA_CH25_I2CA0_RX, UDMA_MODE_BASIC, ulReadSize, UDMA_SIZE_8, UDMA_ARB_1, (u8 *)0x40020F00, UDMA_SRC_INC_NONE, ucReadBuffer, UDMA_DST_INC_8); MAP_I2CMasterSlaveAddrSet(I2CA0_BASE,ucDevAddr,true); MAP_I2CMasterBurstLengthSet(I2CA0_BASE,ulReadSize); MAP_I2CMasterIntClear(I2CA0_BASE); MAP_I2CMasterControl(I2CA0_BASE,I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START| I2C_MASTER_CMD_FIFO_BURST_RECEIVE_ERROR_STOP); UDMAStartTransfer(UDMA_CH25_I2CA0_RX); osi_SyncObjWait(&signal_i2cDone,OSI_WAIT_FOREVER); Message("Receive done 0!\r\n"); osi_SyncObjWait(&signal_i2cReadDone,OSI_WAIT_FOREVER); Message("Receive done 1!\r\n"); //UART_PRINT("Err:%x\r\n",MAP_I2CMasterErr (I2CA0_BASE)); } /*if(ulReadSize!=0) { MAP_I2CMasterSlaveAddrSet(I2CA0_BASE,ucDevAddr,true); MAP_I2CMasterBurstLengthSet(I2CA0_BASE,ulReadSize); MAP_I2CMasterIntClear(I2CA0_BASE); MAP_I2CMasterControl(I2CA0_BASE,I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START| I2C_MASTER_CMD_FIFO_BURST_RECEIVE_ERROR_STOP); while(ulReadSize!=0) { *ucReadBuffer=(u8)MAP_I2CFIFODataGet(I2CA0_BASE); ucReadBuffer++; ulReadSize--; } }*/ UART_PRINT("Err:%x\r\n",MAP_I2CFIFOStatus (I2CA0_BASE)); while(MAP_I2CFIFODataGetNonBlocking (I2CA0_BASE,&rdData)>0) { UART_PRINT("%02x ",rdData); } UART_PRINT("\r\nErr:%x\r\n",MAP_I2CFIFOStatus (I2CA0_BASE)); osi_LockObjUnlock(&lock_i2cTrans); return 0; }
the interrupt handler
static void I2CIntHandler() { unsigned long ulStatus = MAP_I2CMasterIntStatusEx(I2CA0_BASE,false); MAP_I2CMasterIntClearEx(I2CA0_BASE,ulStatus); if( ulStatus & I2C_MASTER_INT_STOP ) { osi_SyncObjSignal(&signal_i2cDone); } if(ulStatus & I2C_MASTER_INT_RX_DMA_DONE) { osi_SyncObjSignal(&signal_i2cReadDone); readDone=1; } }
Regards,