My MSP432 device act as I2C slave and like to receive data with using DMA. I am expecting to receive the data in the interrupt I2C0_IRQHandler().
- Do I have to run DMA with I2C FIFO?
- Can I poll the INT status flag for receiving data instead of receiving data inside the INT?
- Do I need to reset DMA after finish receiving data?
The following is my setup. The interrupt didn't trigger for FIFO. Do I miss anything?
Void I2C0_IRQHandler(UArg arg)
{
uint32_t getStatus;
getStatus = MAP_I2CSlaveIntStatusEx(I2C0_BASE, true);
MAP_I2CSlaveIntClearEx(I2C0_BASE, getStatus);
if(getStatus & (I2C_SLAVE_INT_RX_FIFO_FULL | I2C_SLAVE_INT_RX_DMA_DONE))
{
// Try to get data here:
}
}
static void initI2C(void)
{
Hwi_Params hwiParams;
Hwi_Handle handle;
Error_Block eb;
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
while(!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB)))
{
}
MAP_GPIOPinConfigure(GPIO_PB2_I2C0SCL);
MAP_GPIOPinConfigure(GPIO_PB3_I2C0SDA);
MAP_GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
MAP_GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
/* Since there are no board pull up's we shall enable the weak internal
* pull up */
GPIOB->PUR |= (GPIO_PIN_2 | GPIO_PIN_3);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
while(!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0)))
{
}
Hwi_Params_init(&hwiParams);
Error_init(&eb);
hwiParams.priority = 2;
handle = Hwi_create(INT_I2C0, I2C0_IRQHandler, &hwiParams, &eb);
if(handle == NULL)
while(1) {};
MAP_I2CSlaveEnable(I2C0_BASE);
MAP_I2CSlaveInit(I2C0_BASE, SLAVE_ADDRESS);
MAP_I2CRxFIFOConfigSet(I2C0_BASE, I2C_FIFO_CFG_RX_SLAVE |
I2C_FIFO_CFG_RX_SLAVE_DMA |
I2C_FIFO_CFG_RX_TRIG_4);
MAP_I2CRxFIFOFlush(I2C0_BASE);
MAP_I2CSlaveIntEnableEx(I2C0_BASE, (I2C_SLAVE_INT_RX_FIFO_FULL | I2C_SLAVE_INT_START));
/* Enable the Interrupt in the NVIC from I2C Master */
MAP_IntEnable(INT_I2C0);
}
static void initI2CuDMA(void)
{
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
MAP_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
while(!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)))
{
}
MAP_uDMAEnable();
MAP_uDMAControlBaseSet(pui8ControlTable);
MAP_uDMAChannelAssign(UDMA_CH0_I2C0RX);
MAP_uDMAChannelAttributeDisable(UDMA_CH0_I2C0RX,
UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
MAP_uDMAChannelControlSet(UDMA_CH0_I2C0RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE |
UDMA_DST_INC_8 | UDMA_ARB_1 | UDMA_NEXT_USEBURST);
MAP_uDMAChannelTransferSet(UDMA_CH0_I2C0RX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *)&I2C0->FIFODATA,
(void *)&g_ui8RxBufA,
3);
MAP_uDMAChannelEnable(UDMA_CH0_I2C0RX);
}