cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Slave Transmit Problems

JM?�l
Associate II

I want to use a STM32L151RDT6 as I2C slave and a USB to I2C bridge from FTDI as master.

Reading command with the slave from the master is possible. But when i try to transmit data to the master the slave is releasing the SDA Line after the acknowledge. But the master expected a low SDA line bevor he start clocking for the databyte.

I had oriented on the example code: STM32Cube/Repository/STM32Cube_FW_L1_V1.9.0/Projects/NUCLEO-L152RE/Examples/I2C/I2C_TwoBoards_RestartComIt

0690X000008wBHoQAM.bmp

/* USER CODE BEGIN 2 */
	HAL_GPIO_WritePin(LED_gn_GPIO_Port, LED_gn_Pin, SET);
 
	/* The board receives the message and sends it back */
 
	/*##-3- Put I2C peripheral in listen mode process ###########################*/
	if (HAL_I2C_EnableListen_IT(&hi2c1) != HAL_OK) {
		/* Transfer error in reception process */
		Error_Handler();
	}
 
	/*##-4- Wait Address Match Code event ######################################*/
	/*  Before starting a transfer, you need to wait a Master request event.
	 For simplicity reasons, this example is just waiting till an Address callback event,
	 but application may perform other tasks while transfer operation is ongoing. */
	while (uwTransferRequested != 1) {
	}
 
	/*##-3- Put I2C peripheral in reception process ############################*/
	if (HAL_I2C_Slave_Seq_Receive_IT(&hi2c1,aRxBuffer,
	RXBUFFERSIZE, I2C_FIRST_FRAME) != HAL_OK) {
		/* Transfer error in reception process */
		Error_Handler();
	}
 
	/*##-4- Wait for the end of the transfer ###################################*/
	/*  Before starting a new communication transfer, you need to check the current
	 state of the peripheral; if it’s busy you need to wait for the end of current
	 transfer before starting a new one.
	 For simplicity reasons, this example is just waiting till the end of the
	 transfer, but application may perform other tasks while transfer operation
	 is ongoing. */
	while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){
 
	}
 
	/*##-5- Start the transmission process  #####################################*/
	/* While the I2C in reception process, user can transmit data through
	 "aTxBuffer" buffer */
	aTxBuffer[0] = 13;
	if (HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1,aTxBuffer,
	TXBUFFERSIZE, I2C_LAST_FRAME) != HAL_OK) {
		/* Transfer error in transmission process */
		Error_Handler();
	}
 
	while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY) {
	}
 
  /* USER CODE END 2 *
/* USER CODE BEGIN 4 */
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *I2cHandle) {
	/* Turn LED2 off: Transfer in transmission process is correct */
	HAL_GPIO_WritePin(LED_gb_GPIO_Port, LED_gb_Pin, RESET);
}
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) {
	/* Turn LED2 on: Transfer in reception process is correct */
	HAL_GPIO_WritePin(LED_gb_GPIO_Port, LED_gb_Pin, SET);
}
/**
 * @brief  Slave Address Match callback.
 * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
 *                the configuration information for the specified I2C.
 * @param  TransferDirection: Master request Transfer Direction (Write/Read), value of @ref I2C_XferOptions_definition
 * @param  AddrMatchCode: Address Match Code
 * @retval None
 */
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection,
		uint16_t AddrMatchCode) {
	uwTransferRequested = 1;
}
 
/**
 * @brief  Listen Complete callback.
 * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
 *                the configuration information for the specified I2C.
 * @retval None
 */
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) {
}
 
/**
 * @brief  I2C error callbacks.
 * @param  I2cHandle: I2C handle
 * @note   This example shows a simple way to report transfer error, and you can
 *         add your own implementation.
 * @retval None
 */
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle) {
	/** Error_Handler() function is called when error occurs.
	 * 1- When Slave don't acknowledge it's address, Master restarts communication.
	 * 2- When Master don't acknowledge the last data transferred, Slave don't care in this example.
	 */
	if (HAL_I2C_GetError(I2cHandle) != HAL_I2C_ERROR_AF) {
		Error_Handler();
	}
}
/* USER CODE END 4 */
/* I2C1 init function */
void MX_I2C1_Init(void)
{
 
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 26;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */
 
  /* USER CODE END I2C1_MspInit 0 */
  
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration    
    PB8     ------> I2C1_SCL
    PB9     ------> I2C1_SDA 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    /* I2C1 clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
 
    /* I2C1 interrupt Init */
    HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
    HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
  /* USER CODE BEGIN I2C1_MspInit 1 */
 
  /* USER CODE END I2C1_MspInit 1 */
  }
}

0 REPLIES 0