cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743VGT6 how to use slave I2C+DMA

AngusHZ
Associate II

STM32H743VGT6 how to use slave I2C+DMA
Currently, this usage is fine. However, when using the DMA function, it will trigger an ER interrupt.
HAL_I2C_Slave_Seq_Receive_DMA, How to use it? Are there any examples?

// 从机地址匹配回调函数
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
    if (hi2c->Instance == I2C1)
    {
        if (TransferDirection == I2C_DIRECTION_TRANSMIT)
        {
            Rx_len = 0;
            memset(I2C_rxBuffer,0,4);
            HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, I2C_rxBuffer, 1, I2C_FIRST_AND_LAST_FRAME);
        }
        else
        {
            HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, I2C_txBuffer, Tx_len, I2C_FIRST_AND_LAST_FRAME);
        }
    }
}

 

2 REPLIES 2
mbarg.1
Lead

I do use I2c+DMA with AZrtos - up to you to port to your OS

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1 __attribute__((weak));
I2C_HandleTypeDef hi2c2 __attribute__((weak));
I2C_HandleTypeDef hi2c3 __attribute__((weak));
I2C_HandleTypeDef hi2c4 __attribute__((weak));

/* Private function prototypes -----------------------------------------------*/

/* Global variables ----------------------------------------------------------*/

I2cServer_t hI2cServer;
#if 0
#ifdef I2C_USE_1
ALIGN_32BYTES (uint8_t hi2cbuffRx[32]) __attribute__((section(".DmaArraySection")));
ALIGN_32BYTES (uint8_t hi2cbuffTx[32]) __attribute__((section(".DmaArraySection")));
#endif
#endif

#ifdef I2C_USE_2
ALIGN_32BYTES (uint8_t hi2cbuffRx[I2C_TX_BUFFER_SIZE]) __attribute__((section(".DmaArraySection")));
ALIGN_32BYTES (uint8_t hi2cbuffTx[I2C_TX_BUFFER_SIZE]) __attribute__((section(".DmaArraySection")));
#endif
#ifdef I2C_USE_3
ALIGN_32BYTES (uint8_t hi2cbuffRx[32]) __attribute__((section(".DmaArraySection")));
ALIGN_32BYTES (uint8_t hi2cbuffTx[32]) __attribute__((section(".DmaArraySection")));
#endif
#ifdef I2C_USE_4
ALIGN_32BYTES (uint8_t hi2cbuffRx[32]) __attribute__((section(".DmaArraySection")));
ALIGN_32BYTES (uint8_t hi2cbuffTx[32]) __attribute__((section(".DmaArraySection")));
#endif

/* Private user code ---------------------------------------------------------*/

/* HAL functions redefined ---------------------------------------------------*/

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    HAL_I2C_MasterTxCpltCallback						  PORTABLE C      */
/*                                                                        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Mike Bargauan														  */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This functions set event according to interrupt					  */
/*		and wakes up calling thread.									  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*		hi2c					-	ptr to i2c andle					  */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/* 	  	tx_event_flags_set												  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    i2c hardware			                              				  */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/**************************************************************************/
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) {

#ifdef I2C_USE_1
	if (hi2c == &hi2c1) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt1, TX_OR);
	}
#endif
#ifdef I2C_USE_2
	if (hi2c == &hi2c2) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt2, TX_OR);
	}
#endif
#ifdef I2C_USE_3
	if (hi2c == &hi2c3) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt3, TX_OR);
	}
#endif
//#ifdef I2C_USE_4
	if (hi2c == &hi2c4) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt4, TX_OR);
	}
//#endif
	return;
}

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    HAL_I2C_MasterRxCpltCallback						  PORTABLE C      */
/*                                                                        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Mike Bargauan														  */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This functions set event according to interrupt					  */
/*		and wakes up calling thread.									  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*		hi2c					-	ptr to i2c andle					  */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/* 	  	tx_event_flags_set												  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    i2c hardware			                              				  */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/**************************************************************************/
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) {

#ifdef I2C_USE_1
	if (hi2c == &hi2c1) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt1, TX_OR);
	}
#endif
#ifdef I2C_USE_2
	if (hi2c == &hi2c2) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt2, TX_OR);
	}
#endif
#ifdef I2C_USE_3
	if (hi2c == &hi2c3) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt3, TX_OR);
	}
#endif
//#ifdef I2C_USE_4
	if (hi2c == &hi2c4) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_TxRxCplt4, TX_OR);
	}
//#endif
	return;
}

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    HAL_I2C_MemRxCpltCallback							  PORTABLE C      */
/*                                                                        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Mike Bargauan														  */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This functions set event according to interrupt					  */
/*		and wakes up calling thread.									  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*		hi2c					-	ptr to i2c andle					  */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/* 	  	tx_event_flags_set												  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    i2c hardware			                              				  */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/**************************************************************************/
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) {

#ifdef I2C_USE_1
	if (hi2c == &hi2c1) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_MemTxRxCplt1, TX_OR);
	}
#endif
#ifdef I2C_USE_2
	if (hi2c == &hi2c2) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_MemTxRxCplt2, TX_OR);
	}
#endif
#ifdef I2C_USE_3
	if (hi2c == &hi2c3) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_MemTxRxCplt3, TX_OR);
	}
#endif
//#ifdef I2C_USE_4
	if (hi2c == &hi2c4) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_MemTxRxCplt4, TX_OR);
	}
//#endif
	return;
}

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    HAL_I2C_ErrorCallback								  PORTABLE C      */
/*                                                                        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Mike Bargauan														  */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This functions set event according to interrupt					  */
/*		and wakes up calling thread.									  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*		hi2c					-	ptr to i2c andle					  */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/* 	  	tx_event_flags_set												  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    i2c hardware			                              				  */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/**************************************************************************/
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) {

#ifdef I2C_USE_1
	if (hi2c == &hi2c1) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_Err1, TX_OR);
	}
#endif
#ifdef I2C_USE_2
	if (hi2c == &hi2c2) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_Err2, TX_OR);
	}
#endif
#ifdef I2C_USE_3
	if (hi2c == &hi2c3) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_Err3, TX_OR);
	}
#endif
//#ifdef I2C_USE_4
	if (hi2c == &hi2c4) {
		tx_event_flags_set(&hI2cServer.i2c_event_group, I2C_EVENT_Err4, TX_OR);
	}
//#endif
	return;
}

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    mb_I2C_write										  PORTABLE C      */
/*                                                                        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Mike Bargauan														  */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This functions write data to I2C with DMA							  */
/*		and waits for completion.										  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*		mb_i2c_cmd_t h			ptr to handle with input and output val   */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*  GLOBALS              								                  */
/*                                                                        */
/*		  hi2cbuffTx			Ptr to tx buffer                          */
/*		                                                                  */
/*  CALLS                                                                 */
/*                                                                        */
/* 	  	HAL_I2C_Master_Transmit_DMA										  */
/* 	  	tx_event_flags_set												  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    I2C Device driver		                              				  */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/**************************************************************************/
void mb_I2C_write(mb_i2c_cmd_t *h) {

	/*	clean cache		*/
	SCB_CleanDCache_by_Addr((uint32_t*) hi2cbuffTx, I2C_TX_BUFFER_SIZE);
	/*	start transmit data with DMA		*/
	h->event = HAL_I2C_Master_Transmit_DMA(h->hi2c, h->slave, hi2cbuffTx, h->size);
	if (h->event != HAL_OK) {
		/*	we have a HAL error -busy or other - stop DMA		*/
		HAL_DMA_Abort(h->hi2c->hdmatx);
		return;
	}
	/*	wait for event or timeout		*/
	if( tx_event_flags_get(&hI2cServer.i2c_event_group, I2C_ANY_EVENT, TX_OR_CLEAR, (ULONG *)&h->event, h->eventWait) == TX_SUCCESS) {
			/*	we got an event that operation was completed		*/
	} else {
		/*	we got a timeout  - no device present? - stop DMA		*/
		HAL_DMA_Abort(h->hi2c->hdmatx);
		/*	set event		*/
		h->event = I2C_EVENT_Timeout;
	}
}

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    mb_I2C_read										  PORTABLE C      */
/*                                                                        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Mike Bargauan														  */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This functions read data from I2C with DMA						  */
/*		and waits for completion.										  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*		mb_i2c_cmd_t h		ptr to handle with input and output val 	  */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/* 	  	tx_event_flags_set												  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    I2C Device driver		                              				  */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/**************************************************************************/
void mb_I2C_read(mb_i2c_cmd_t *h) {
	/*	start receive data with DMA		*/
	h->event = HAL_I2C_Master_Receive_DMA(h->hi2c, h->slave, hi2cbuffRx, h->size);
	if (h->event != HAL_OK) {
		/*	we have a HAL error -busy or other		*/
		/*	stop DMA		*/
		HAL_DMA_Abort(h->hi2c->hdmarx);
		return;
	}
	/*	wait for event or timeout		*/
	if(tx_event_flags_get(&hI2cServer.i2c_event_group, I2C_ANY_EVENT, TX_OR_CLEAR, (ULONG *)&h->event, h->eventWait) == TX_SUCCESS) {
	} else {
		/*	we got a timeout  - no device present?		*/
		/*	set returned status		*/
		h->event = I2C_EVENT_Timeout;
	}
}

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    mb_I2C_mem_read										  PORTABLE C      */
/*                                                                        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Mike Bargauan														  */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This functions read data from I2C memory with DMA					  */
/*		and waits for completion.										  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*		mb_i2c_cmd_t h		ptr to handle with input and output val		  */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/* 	  	tx_event_flags_set												  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    I2C Device driver		                              				  */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/**************************************************************************/
void mb_I2C_mem_read(mb_i2c_cmd_t *h) {

	h->event = HAL_I2C_Mem_Read_DMA(h->hi2c, h->slave, h->address, I2C_MEMADD_SIZE_8BIT, hi2cbuffRx, h->size);
	if (h->event != HAL_OK) {
		/*	we have a HAL error -busy or other		*/
		/*	stop DMA		*/
		HAL_DMA_Abort(h->hi2c->hdmatx);
		HAL_DMA_Abort(h->hi2c->hdmarx);
		return;
	}
	/*	wait for event or timeout		*/
	if(tx_event_flags_get(&hI2cServer.i2c_event_group, I2C_ANY_EVENT, TX_OR_CLEAR, (ULONG*) &h->event, h->eventWait) == TX_SUCCESS) {
		SCB_InvalidateDCache_by_Addr((uint32_t*) hi2cbuffRx, I2C_RX_BUFFER_SIZE);
	} else {
		/*	we got a timeout  - no device present?		*/
		/*	stop DMA		*/
		HAL_DMA_Abort(h->hi2c->hdmatx);
		HAL_DMA_Abort(h->hi2c->hdmarx);
		/*	set returned status		*/
		h->event = I2C_EVENT_Timeout;
	}
}

Have the slave i2c+DMA?
Master and slave is different