cancel
Showing results for 
Search instead for 
Did you mean: 

I2C2 Stops working after Power Supply Reset

JMart.12
Associate

Hi All,

I'm using an NUCLEO-F103RB with STM32F103RB

Basically when I run the code or debug the CODE with the IDE every works fine.

But if unplugged the STM from the computer and plug it again the code stays stuck.

After the power supply reset is getting stuck here:

while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));

void  prvSendMessageI2C2(uint8_t int8AddressI2C, uint8_t byte){
	I2C_AcknowledgeConfig(I2C2, ENABLE);
	while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
	I2C_GenerateSTART(I2C2, ENABLE);
	while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));
	I2C_Send7bitAddress(I2C2, int8AddressI2C, I2C_Direction_Transmitter);
	//vTaskDelay( ( TickType_t ) 1000 / portTICK_PERIOD_MS  );
	while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
	I2C_SendData(I2C2,byte);
	while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	I2C_GenerateSTOP(I2C2, ENABLE);

EDIT: I found this workaroud: If I add vTaskDelay( ( TickType_t ) 600 / portTICK_PERIOD_MS ); on line 4 the issue is not reproduceable. But I really would like to solve this in anoter way. 

void  prvSendMessageI2C2(uint8_t int8AddressI2C, uint8_t byte){
	I2C_AcknowledgeConfig(I2C2, ENABLE);
	while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
	vTaskDelay( ( TickType_t ) 600 / portTICK_PERIOD_MS  );
	I2C_GenerateSTART(I2C2, ENABLE);
	while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));
	I2C_Send7bitAddress(I2C2, int8AddressI2C, I2C_Direction_Transmitter);
	//vTaskDelay( ( TickType_t ) 1000 / portTICK_PERIOD_MS  );
	while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
	I2C_SendData(I2C2,byte);
	while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	I2C_GenerateSTOP(I2C2, ENABLE);
}

Here is my full code in FreeRTOS:

/**
  ******************************************************************************
 
  ******************************************************************************
*/
 
 
/*
 *
 * LED blink
 *
 */
 
/* Standard includes. */
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include "time.h"
 
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
 
struct stReceiveI2C {
   char  values[15];
}stReceiveI2C;
 
 
 
/* Configure RCC clock at 64 MHz */
static void prvSetupRCCHSI( void );  
 
 /* Configure GPIO. */
static void prvSetupGPIO( void );
 
/* Simple I2C2 read task. */
static void prvI2C2ReadTask( void *pvParameters );
 
/********** Useful functions **********/
/* USART2 configuration. */
static void prvSetupUSART2( void );
 
/* I2C2 configuration. */
static void prvSetupI2C2( void );
 
/* USART2 send message. */
static void prvSendMessageUSART2(char *message);
 
/* I2C2 read message. */
 
void prvSendMessageI2C2(uint8_t int8AddressI2C, uint8_t byte);
 
struct stReceiveI2C prvReceivesMessagesI2C2(uint8_t int8AddressI2C, uint8_t int8Iterations);
 
void prvEndComunicationI2C2(uint8_t int8AddressI2C);
 
 
 
 
 
/***************************************/
 
 
/* Task 1 handle variable. */
TaskHandle_t HandleTask1;
 
 
 
 
int main( void )
{
	/*Setup the hardware, RCC, GPIO, etc...*/
 
    prvSetupRCCHSI();
    prvSetupGPIO();
    prvSetupUSART2();
    prvSetupI2C2();
 
	/* Create the tasks */
 
 	xTaskCreate( prvI2C2ReadTask, "I2C2Read", configMINIMAL_STACK_SIZE, NULL, 1, &HandleTask1 );
 
 
	/* Start the scheduler. */
	vTaskStartScheduler();
 
	/* Will only get here if there was not enough heap space to create the idle task. */
	return 0;
}
/*-----------------------------------------------------------*/
 
 
 
static void prvI2C2ReadTask( void *pvParameters )
{
	struct stReceiveI2C stReceiveData;
	uint8_t address= 200;
    for( ;; )
	{
    	/*Send I2C Messages*/
    	prvSendMessageI2C2(address,'R');
    	vTaskDelay( ( TickType_t ) 600 / portTICK_PERIOD_MS  );
    	/*Receives I2C Messages*/
    	stReceiveData=prvReceivesMessagesI2C2(address,11);
    	prvEndComunicationI2C2(address);
 
    	char buf[11];
    	sprintf(buf,"new read: ");
    	prvSendMessageUSART2(buf);
    	prvSendMessageUSART2(stReceiveData.values);
 
	}
}
 
 
 
/*-----------------------------------------------------------*/
 
 
 
static void prvSetupRCCHSI( void )
{
	RCC_HCLKConfig(RCC_SYSCLK_Div1);
	RCC_PCLK1Config(RCC_HCLK_Div2);
	RCC_PCLK2Config(RCC_HCLK_Div1);
 
	RCC_HSICmd(ENABLE);
	FLASH_SetLatency(FLASH_Latency_2);
 
 
 
	RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);
	RCC_PLLCmd(ENABLE);
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
 
	while(RCC_GetSYSCLKSource() != 0x08);
}
/*-----------------------------------------------------------*/
 
 
static void prvSetupGPIO( void )
{
    /* GPIO configuration */
    GPIO_InitTypeDef GPIO_InitStructure;
 
    /* Enable GPIOB clock */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE );
 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
}
/*-----------------------------------------------------------*/
 
 
 
static void prvSetupUSART2( void )
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
 
    /* USART2 is configured as follow:
        - BaudRate = 115200 baud
        - Word Length = 8 Bits
        - 1 Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled */
 
    /* Enable GPIOA clock */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE );
 
    /* USART Periph clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
 
    /* Configure the USART2 */
    USART_Init(USART2, &USART_InitStructure);
    /* Enable the USART2 */
    USART_Cmd(USART2, ENABLE);
 }
 
/*-----------------------------------------------------------*/
 
static void prvSetupI2C2( void )
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
 
 
    /* Enable GPIOB clock */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE );
 
    /* I2C2 Periph clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
 
    /*PB7 -> I2C2 SDA  & PB8 -> I2C2 SCL */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
    /* Initialize I2C */
    I2C_DeInit(I2C2);
    I2C_InitStructure.I2C_ClockSpeed = 100000;
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 1;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
 
    /* Configure the I2C2 */
    I2C_Init(I2C2, &I2C_InitStructure);//I2Cx->I2C2
 
    /* Enable the USART2 */
    I2C_Cmd(I2C2, ENABLE);//I2Cx->I2C2
 
 
 }
 
/*-----------------------------------------------------------*/
 
 
/* This is a blocking send USART function */
static void prvSendMessageUSART2(char *message)
{
uint16_t cont_aux=0;
 
    while(cont_aux != strlen(message))
    {
        USART_SendData(USART2, (uint8_t) message[cont_aux]);
        while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
        {
        }
        cont_aux++;
    }
}
 
 
/*-----------------------------------------------------------*/
 
void  prvSendMessageI2C2(uint8_t int8AddressI2C, uint8_t byte){
	I2C_AcknowledgeConfig(I2C2, ENABLE);
	while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
	I2C_GenerateSTART(I2C2, ENABLE);
	while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));
	I2C_Send7bitAddress(I2C2, int8AddressI2C, I2C_Direction_Transmitter);
	//vTaskDelay( ( TickType_t ) 1000 / portTICK_PERIOD_MS  );
	while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
	I2C_SendData(I2C2,byte);
	while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	I2C_GenerateSTOP(I2C2, ENABLE);
}
 
/*-----------------------------------------------------------*/
 
struct stReceiveI2C prvReceivesMessagesI2C2(uint8_t int8AddressI2C, uint8_t int8Iterations){
	struct stReceiveI2C stReceiveData;
	int i;
	if (int8Iterations <= 15){
		I2C_GenerateSTART(I2C2,ENABLE);
		while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));
		I2C_Send7bitAddress(I2C2, int8AddressI2C, I2C_Direction_Receiver);
		while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
		for ( i=0; i<=int8Iterations; i++){
			while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED));
			stReceiveData.values[i]=I2C_ReceiveData(I2C2);
		}
		return stReceiveData;
	}
		else{
			return stReceiveData;
		}
}
 
/*-----------------------------------------------------------*/
 
void prvEndComunicationI2C2(uint8_t int8AddressI2C){
	I2C_AcknowledgeConfig(I2C2, DISABLE);
	I2C_GenerateSTOP(I2C2, ENABLE);
	while(I2C_GetFlagStatus(I2C2,I2C_FLAG_STOPF));
}
/*-----------------------------------------------------------*/
 
 

2 REPLIES 2

Which STM32?

Clear the local/auto variables, also watch how you return them

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

NUCLEO-F103RB with STM32F103RB