2023-05-21 12:29 PM - edited 2023-11-20 04:58 AM
Hello,
I have developed a code in FreeRTOS mode that contains two main tasks. The first one check if I have received an RX buffer on the I2C bus, and the second one manage the data that has been received.
However, after receiving the first buffer, I am getting HAL_I2C_STATE_BUSY_RX, and I cannot transmit a response to the master device but I'm able to receive another RX buffer . Can anyone please help me?
I'm using I2C in DMA normal mode.
32-> HAL_I2C_STATE_READY
34-> HAL_I2C_STATE_BUSY_RX
2023-05-23 01:15 PM
Hello,
In this case, what should I do to check if I have received an I2C bus message from the master? I am currently using the method in the code below, but I am getting the I2C state as "HAL_I2C_BUSY_RX." Despite that I'm able to receive data from the master, I am unable to transmit any data.
if(HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)
{
ret = HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t*)&RX_I2C_Buffer, sizeof(RX_I2C_Buffer));
}
2023-05-23 06:50 PM
Sigh...
What do you think HAL_I2C_SlaveRxCpltCallback() does, or what does it mean when it is called? Likewise, what does HAL_I2C_SlaveTxCpltCallback() do/mean? You had code in one of these functions in your first post. If you don't know, look at the HAL source, or some of the I2C examples in the HAL library (there might not be a DMA example, but the IT [interrup] example will use the same functions and concepts).
Get rid of all of the HAL_I2C_GetState() calls - that function is not reliable when multiple threads are accessing the same I2C port.
2023-05-25 12:51 AM
The HAL_I2C_MasterTxCpltCallback() function is automatically called to handle the completion of a master transmission (Tx) operation over the I2C bus.
Similarly, the HAL_I2C_MasterRxCpltCallback() function is automatically called to handle the completion of a master reception (Rx) operation over the I2C bus.
For the slave device, I initiate the reception mode for I2C by calling
HAL_I2C_Slave_Receive_DMA(). If HAL_I2C_MasterRxCpltCallback()
is invoked as a callback, I handle the received data. In the callback function, I switch my I2C to the transmission mode by calling HAL_I2C_Slave_Transmit_DMA() if HAL_I2C_SlaveTxCpltCallback() is called back. In case HAL_I2C_SlaveTxCpltCallback() is invoked as a callback, I switch my I2C back to the receiving mode by calling
HAL_I2C_Slave_Receive_DMA().
.
For the master device, I initiate the transmission mode for I2C by calling
HAL_I2C_Master_Transmit_DMA(). If HAL_I2C_MasterTxCpltCallback()
is called back, I switch my I2C to the receiving mode by calling
HAL_I2C_Master_Receive_DMA(). Subsequently, if HAL_I2C_MasterRxCpltCallback() is invoked as a callback, I handle the response received from the slave. Finally, I switch my I2C back to the transmission mode by calling HAL_I2C_Master_Transmit_DMA()
I'm able to transmit data from the master device and receive it on the slave device successfully. However, I'm encountering difficulties when trying to perform the reverse operation, which is transmitting from the slave device and receiving on the master device.
.
2023-05-25 06:59 AM
Can you make a small simple test of the i2c slave operation, without any RTOS?
2023-05-25 12:52 PM - edited 2023-11-20 04:58 AM
This is the master code
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
HAL_StatusTypeDef ret;
uint16_t status = 0;
uint8_t txbuffer[8] = {0};
uint8_t rxbuffer[8] = {0};
uint8_t RX_FLAG = 0;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef hdma_i2c1_rx;
DMA_HandleTypeDef hdma_i2c1_tx;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
/*for(int i = 1; i<20; i++){
ret = HAL_I2C_IsDeviceReady(&hi2c1, i, 3, 100);
if(ret == HAL_OK){
address = i;
}
while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){
}
}*/
txbuffer[0] = 0x01;
txbuffer[1] = 0xFF;
txbuffer[2] = 0xFF;
txbuffer[3] = 0xFF;
txbuffer[4] = 0xFF;
txbuffer[5] = 0xFF;
txbuffer[6] = 0xFF;
txbuffer[7] = 0xFF;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef*hi2c)
{
HAL_I2C_Master_Receive_DMA(&hi2c1, 16, rxbuffer, sizeof(rxbuffer));
}
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef*hi2c)
{
HAL_I2C_Master_Transmit_DMA(&hi2c1, 16, txbuffer, sizeof(txbuffer));
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin){
case GPIO_PIN_11:
status = HAL_I2C_GetState(&hi2c1);
ret = HAL_I2C_Master_Transmit_DMA(&hi2c1, 16, txbuffer, sizeof(txbuffer));
if (ret == HAL_OK)
{
}
break;
case GPIO_PIN_12:
break;
default:
break;
}
}
This is the slave code
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
HAL_StatusTypeDef ret;
uint8_t rxbuffer[8];
uint8_t txbuffer[8];
uint8_t status;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef hdma_i2c1_rx;
DMA_HandleTypeDef hdma_i2c1_tx;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
if (HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)rxbuffer, sizeof(rxbuffer)) != HAL_OK)
{
Error_Handler();
}
txbuffer[0] = 11;
txbuffer[1] = 12;
txbuffer[2] = 13;
txbuffer[3] = 14;
txbuffer[4] = 15;
txbuffer[5] = 16;
txbuffer[6] = 17;
txbuffer[7] = 18;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
if (HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)rxbuffer, sizeof(rxbuffer)) != HAL_OK)
{
Error_Handler();
}
}
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c){
if(rxbuffer[0] == 0x01)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
if (HAL_I2C_Slave_Transmit_DMA(&hi2c1, (uint8_t *)txbuffer, sizeof(txbuffer)) != HAL_OK)
{
Error_Handler();
}
}
}
2024-04-09 05:46 AM
hello @Mabou.1
When the state is at HAL_I2C_STATE_BUSY_RX, it indicates that the receive process is still in progress.
It is important to verify that all expected data has been received or not by checking the XferCount and XferSize values.