This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Hard fault from I2C DMA read

Other Parts Discussed in Thread: TM4C1294NCPDT

I can transfer I2C Tx(DMAWrite) and see the buffer was sent and ack by Logic Analyzer, but got an fard fault when receiving from I2C Rx (DMARead).

Please help me to check the details, below is FYI, thanks.

// main flow
	uint32_t u32Loop;
	for(u32Loop = 0; u32Loop<32; u32Loop++)
	{

	}

	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
	MAP_GPIOPinTypeGPIOInput(PACKAGESEL_PIN_BASE, PACKAGESEL_PIN);
	MAP_GPIOPadConfigSet(PACKAGESEL_PIN_BASE, PACKAGESEL_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU);

	g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_12MHZ |
	                                        SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
	                                        SYSCTL_CFG_VCO_480), 120000000);

	//gpio port function init
	PortFunctionInit();

#ifdef DEBUG
//#message "This code will work the DEBUG Mode."
	ConfigureDBGUART();
#else
	ConfigureCDCUART();
#endif

	DEBUG_PRINT("ConfigureGPIO\n");
	ConfigureGPIO();

	I2CDMAInitial();
	I2C0_Initial(0x41);
	gu8TxBuf[0] = 20;
	I2C0_DMAWrite(gu8TxBuf, 32);
	I2C0_DMARead(gu8RxBuf, 32); // hard fault here
//
void I2CDMAInitial(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA); IntEnable(INT_UDMAERR); uDMAEnable(); uDMAControlBaseSet(pui8ControlTable); IntEnable(INT_UDMA); uDMAChannelAssign(UDMA_CH1_I2C0TX); uDMAChannelAttributeDisable(UDMA_CH1_I2C0TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); uDMAChannelControlSet(UDMA_CH1_I2C0TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); uDMAChannelAssign(UDMA_CH0_I2C0RX); uDMAChannelAttributeDisable(UDMA_CH0_I2C0RX, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)); uDMAChannelControlSet(UDMA_CH0_I2C0RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); uDMAChannelAssign(UDMA_CH3_I2C1TX); uDMAChannelAttributeDisable(UDMA_CH3_I2C1TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); uDMAChannelControlSet(UDMA_CH3_I2C1TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); uDMAChannelAssign(UDMA_CH2_I2C1RX); uDMAChannelAttributeDisable(UDMA_CH2_I2C1RX, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)); uDMAChannelControlSet(UDMA_CH2_I2C1RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); }
void I2C0_DMAWrite(uint8_t *pu8TxBuffer, uint16_t u16Len)
{
	uDMAChannelTransferSet(UDMA_CH1_I2C0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC,
			pu8TxBuffer, ((void *)(I2C0_BASE + I2C_O_FIFODATA)), u16Len);

	uDMAChannelEnable(UDMA_CH1_I2C0TX);

	I2CMasterBurstLengthSet(I2C0_BASE, u16Len);
	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_FIFO_SINGLE_SEND);
}

void I2C0_DMARead(uint8_t *pu8RxBuffer, uint16_t u16Len)
{
	uDMAChannelTransferSet(UDMA_CH0_I2C0RX | UDMA_PRI_SELECT, UDMA_MODE_BASIC,
				((void *)(I2C0_BASE + I2C_O_FIFODATA)), pu8RxBuffer, u16Len);
	
	uDMAChannelEnable(UDMA_CH0_I2C0RX);
}

  • Former Member
    0 Former Member
    Hello,

    Can you provide more specifics about what TI product you're experiencing this with?

    Thanks
    Bill
  • TM4C1294NCPDT, thanks
  • Hello,
    I modified the DMAWrite & DMARead function.
    Finally, I can seperate to do DMAwrite OR DMARead but still have an hard fault when excuting DMAWrite + DMARead...
    Are there any suggestions about this?

    void I2C0_DMAWrite(uint8_t *pu8TxBuffer, uint16_t u16Len)
    {
    uint32_t u32Status;
    if(uDMAChannelModeGet(UDMA_CH1_I2C0TX) == UDMA_MODE_STOP)
    {
    I2CMasterSlaveAddrSet(I2C0_BASE, 0x41, false);
    uDMAChannelTransferSet(UDMA_CH1_I2C0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC,
    pu8TxBuffer, ((void *)(I2C0_BASE + I2C_O_FIFODATA)), u16Len);

    uDMAChannelEnable(UDMA_CH1_I2C0TX);

    I2CMasterBurstLengthSet(I2C0_BASE, u16Len);
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_FIFO_SINGLE_SEND);
    }
    while( I2CMasterBusy(I2C0_BASE));
    }

    void I2C0_DMARead(uint8_t *pu8RxBuffer, uint16_t u16Len)
    {
    if(uDMAChannelModeGet(UDMA_CH0_I2C0RX) == UDMA_MODE_STOP)
    {
    //
    I2CMasterSlaveAddrSet(I2C0_BASE, 0x41, 1);
    I2CMasterBurstLengthSet(I2C0_BASE, u16Len);
    uDMAChannelTransferSet(UDMA_CH0_I2C0RX | UDMA_PRI_SELECT, UDMA_MODE_BASIC,
    ((void *)(I2C0_BASE + I2C_O_FIFODATA)), pu8RxBuffer, u16Len);
    //((void *)(I2C0_BASE + I2C_O_MDR)), pu8RxBuffer, u16Len);
    uDMAChannelEnable(UDMA_CH0_I2C0RX);
    //I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START);
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE);
    }
    while( I2CMasterBusy(I2C0_BASE));
    }
  • Hi,
    Unless you have enabled the I2C0 somewhere else, I do not see SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0) in your code. If you didn't enable I2C then access to the I2C can generate fault.