2017-10-09 10:27 AM
I have been trying to get this to work for a few days now, read over several topics here and nothing I have tried has worked...
I tried all the suggestions here as well
https://community.st.com/0D50X00009XkXWwSAN
nothing helps.I am trying to use the I2C HAL in slave mode, and none of the callbacks get called. I turn an LED on in I2C1_IRQHandler but none of the callbacks seem to get called. Also, even after resetting the CPU the code acts as if there is data ready to be read even before I start a transaction.
Start.
Get Data? 0, 2WHILE: Wait for I2C: 22WHILE: Wait for I2C: 22WHILE: Wait for I2C: 22Code below:
/**
* @brief This function handles I2C1 event global interrupt / I2C1 wake-up interrupt through EXTI line 23.*/void I2C1_IRQHandler(void){ /* USER CODE BEGIN I2C1_IRQn 0 */ HAL_GPIO_WritePin(PWR_LED_GPIO_Port, PWR_LED_Pin, 1); // LED Turns on here - as expected/* USER CODE END I2C1_IRQn 0 */
if (hi2c1.Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) { HAL_I2C_ER_IRQHandler(&hi2c1); HAL_GPIO_WritePin(PWR_LED_GPIO_Port, PWR_LED_Pin, 0); // NO errors so LED stays on. } else { HAL_I2C_EV_IRQHandler(&hi2c1); } /* USER CODE BEGIN I2C1_IRQn 1 *//* USER CODE END I2C1_IRQn 1 */
}int main(void)
{/* USER CODE BEGIN 1 */
char buf[64]; int ret; char buffer[128];/* 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_I2C1_Init(); MX_USART2_UART_Init();/* Initialize interrupts */
MX_NVIC_Init();/* USER CODE BEGIN 2 */
snprintf(buffer, 128, 'Start.\r\n'); HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000); while ((ret = HAL_I2C_GetState(&hi2c1)) != HAL_I2C_STATE_READY) { snprintf(buffer, 128, 'Wait for I2C: %x\r\n', ret); HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000); HAL_Delay(1000); } //ret = HAL_I2C_Slave_Receive_IT(&hi2c1, buf, sizeof(buf)); /* USER CODE END 2 *//* Infinite loop */
/* USER CODE BEGIN WHILE */ while (1) { HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); HAL_Delay(100); ret = HAL_I2C_Slave_Receive_IT(&hi2c1, buf, 1); // Always returns data even if I never did an I2C transcation. snprintf(buffer, 128, 'Get Data? %d, %x\r\n', ret, buf[0]); HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000); while ((ret = HAL_I2C_GetState(&hi2c1)) != HAL_I2C_STATE_READY) { // code gets stuck here forever snprintf(buffer, 128, 'WHILE: Wait for I2C: %x\r\n', ret); HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000); HAL_Delay(1000); } //ret = HAL_I2C_Slave_Receive(&hi2c1, buf, sizeof(buf), 100); /* USER CODE END WHILE *//* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */}
Has anyone got Interrupt driven I2C Slave to work with STM32Cube? Most of the questions/discussions I have read here seem to have not been solved... Should I just switch to another serial interface, or processor?
Any help greatly appreciated.
Thanks,
Mikenull2017-10-09 11:03 AM
>>Should I just switch to another serial interface, or processor?
Depends on what problem is being solved, and why I2C is the right answer.
A board-to-board messaging protocol might be better using something less archaic, like CAN
2017-10-09 11:54 AM
Hello Mike.
ret = HAL_I2C_Slave_Receive_IT(&hi2c1, buf, 1); // Always returns data even if I never did an I2C transcation.
HAL_I2C_Slave_Receive_IT, returns immediately with no valid data. When data received, the weak function HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) called .
So you can define your HAL_I2C_SlaveRxCpltCallback function and wait to be called when slave address transmitted from master mached and data received succesfully.
HAL_I2C_Slave_Receive, in opposite, waits(not returns) until data received.
2017-10-09 01:09 PM
In this case it is for communication between a Hikey ARM SBC running AOSP and an I/O board with the STM32 processor. My available choices would be I2C/SMBUS, SPI and U(S)ART. I was hoping I2C would work, was going to treat the I/O processor like an EEPROM/RAM. I've never had these kinds of issues before with I2C, I think they are specific to either the STM32 chip or the HAL...
Thanks,
Mike
2017-10-09 01:47 PM
The ST I2C peripheral implementation is an overly complicated monster, that's for sure.
2017-10-09 02:32 PM
Thanks for the reply.
I didn't paste it above, but I do have that routine. It never gets called though
:(
/* USER CODE BEGIN 0 */
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef * hi2c){ char buffer[128]; snprintf(buffer, 128, 'HAL_I2C_SlaveRxCpltCallback(%p)\r\n', hi2c); HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000);}/* USER CODE END 0 */
I never see that print message. Quite frustrating...
Thanks,
Mike