AnsweredAssumed Answered

Error when trying to save a variable in an EEPROM using I2C

Question asked by Marco S on Sep 12, 2017
Latest reply on Sep 13, 2017 by Marco S

Hello, I'm following the example in `en.stm32cubef0\STM32Cube_FW_F0_V1.8.0\Projects\STM32091C_EVAL\Examples\I2C\I2C_EEPROM\SW4STM32\STM32091C_EVAL` to try to save a value in the EEPROM (ANT7-M24LR-A) installed in the STM32091C-EVAL evaluation board. At the beginning of the program I try to read the value and it always arrives to the `Error_Handler`function. The same happens if I delete this part and I just try to write in the memory. Below is the code I'm loading:

 

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"

/* USER CODE BEGIN Includes */
#include "string.h"

#define EEPROM_ADDRESS 0xA6

#define EEPROM_PAGESIZE 4 /* RF EEPROM ANT7-M24LR used */
/* EEPROM TIMING is calculated in case of the I2C Clock source is the SYSCLK = 48 MHz */
/* Set TIMING to 0x00E0D3FF to reach 100 KHz speed (Rise time = 50ns, Fall time = 10ns) */
#define EEPROM_TIMING 0x00E0D3FF

/* Maximum Timeout values for flags waiting loops. These timeouts are not based
on accurate values, they just guarantee that the application will not remain
stuck if the I2C communication is corrupted.
You may modify these timeout values depending on CPU frequency and application
conditions (interrupts routines ...). */
#define I2C_XFER_TIMEOUT_MAX 300
/* Maximum number of trials for HAL_I2C_IsDeviceReady() function */
#define EEPROM_MAX_TRIALS 300
#define RXBUFFERSIZE 8
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc;

CAN_HandleTypeDef hcan;

I2C_HandleTypeDef hi2c1;

TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;

UART_HandleTypeDef huart4;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
typedef enum { false, true } bool;
char TextBuffer[64];
static uint16_t fcur=0;
uint16_t preservedVariable = 0;

uint32_t channels[8]={ADC_CHANNEL_0,ADC_CHANNEL_1,ADC_CHANNEL_2,ADC_CHANNEL_3,ADC_CHANNEL_4,ADC_CHANNEL_10,ADC_CHANNEL_11,ADC_CHANNEL_12};
bool tim3stat = false;

uint32_t sampl_e = ADC_SAMPLETIME_239CYCLES_5;
uint32_t sampl_t = ADC_SAMPLETIME_55CYCLES_5;
uint32_t sampl_c = ADC_SAMPLETIME_1CYCLE_5;

uint16_t iter_count = 0;

uint8_t aTxBuffer[2];
/* Buffer used for reception */
uint8_t aRxBuffer[RXBUFFERSIZE];

/* Useful variables during communication */
uint16_t Memory_Address;
int Remaining_Bytes;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_ADC_Init(void);
static void MX_TIM3_Init(void);
static void MX_USART4_UART_Init(void);
static void MX_TIM2_Init(void);
static void MX_CAN_Init(void);
static void MX_I2C1_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void removeadc(void);
void TxCANFrame(uint32_t id, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);

 

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if ((htim->Instance==TIM3)&&(tim3stat==false)){
tim3stat=true;
}
}
/* USER CODE END 0 */

int main(void)
{

/* USER CODE BEGIN 1 */
int status = 0;

/* USER CODE END 1 */

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC_Init();
MX_TIM3_Init();
MX_USART4_UART_Init();
MX_TIM2_Init();
MX_CAN_Init();
MX_I2C1_Init();

/* USER CODE BEGIN 2 */

snprintf(TextBuffer,sizeof(TextBuffer), "\n\n\nBefore\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);
// Remove all ADC channels set by default due to CubeMx
removeadc();
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_Base_Start_IT(&htim2);
HAL_CAN_Init(&hcan);
HAL_I2C_Init(&hi2c1);

//#if 0
/*##-3- Start reading process ##############################################*/
if (HAL_I2C_Mem_Read_DMA(&hi2c1, (uint16_t)EEPROM_ADDRESS, 0, I2C_MEMADD_SIZE_16BIT, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
{
snprintf(TextBuffer,sizeof(TextBuffer), "error\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);
/* Reading process Error */
Error_Handler();
}


/* Wait for the end of the transfer */
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
{
}
//#endif

uint16_t stocked=aRxBuffer[0];


snprintf(TextBuffer,sizeof(TextBuffer), "\n\n\nPreserved main: %i\n", stocked);
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_7|GPIO_PIN_8, GPIO_PIN_SET);

if((stocked >= 0)&&(stocked < 40)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1|GPIO_PIN_7|GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(5000);
}
else if((stocked >= 40)&&(stocked < 80)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(5000);
}
else if((stocked >= 80)&&(stocked < 120)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(5000);
}
else if((stocked >= 120)&&(stocked < 160)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_7, GPIO_PIN_SET);
HAL_Delay(5000);

}
else{/*Do nothing*/}

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (status == 0){
status = 1;
snprintf(TextBuffer,sizeof(TextBuffer), "\n\n\n\n\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);

snprintf(TextBuffer,sizeof(TextBuffer), "\nInitialized\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);
}


if (tim3stat==true){

if((preservedVariable >= 0)&&(preservedVariable < 40)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1|GPIO_PIN_7|GPIO_PIN_8, GPIO_PIN_SET);
}
else if((preservedVariable >= 40)&&(preservedVariable < 80)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_8, GPIO_PIN_SET);
}
else if((preservedVariable >= 80)&&(preservedVariable < 120)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_8, GPIO_PIN_SET);
}
else if((preservedVariable >= 120)&&(preservedVariable < 160)){
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_7, GPIO_PIN_SET);
}
else{/*Do nothing*/}


aTxBuffer[0] = (uint8_t) preservedVariable;
/*##-2- Start writing process ##############################################*/
/* Initialize Remaining Bytes Value to TX Buffer Size */
Remaining_Bytes = 8;
/* Initialize Memory address to 0 since EEPROM write will start from address 0 */
Memory_Address = 0;
/* Since page size is 4 bytes, the write procedure will be done in a loop */
while (Remaining_Bytes > 0)
{
snprintf(TextBuffer,sizeof(TextBuffer), "Before pagesize\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);
/* Write EEPROM_PAGESIZE */
if(HAL_I2C_Mem_Write_DMA(&hi2c1 , (uint16_t)EEPROM_ADDRESS, Memory_Address, I2C_MEMADD_SIZE_16BIT, (uint8_t*)(aTxBuffer + Memory_Address), EEPROM_PAGESIZE)!= HAL_OK)
{
/* Writing process Error */
Error_Handler();
}

/* 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)
{
}

snprintf(TextBuffer,sizeof(TextBuffer), "Before readynewop\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);
/* Check if the EEPROM is ready for a new operation */
while (HAL_I2C_IsDeviceReady(&hi2c1, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2C_XFER_TIMEOUT_MAX) == HAL_TIMEOUT){};

snprintf(TextBuffer,sizeof(TextBuffer), "Before endtransfer\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);
/* Wait for the end of the transfer */
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
{
}

/* Update Remaining bytes and Memory Address values */
Remaining_Bytes -= EEPROM_PAGESIZE;
Memory_Address += EEPROM_PAGESIZE;
}

snprintf(TextBuffer,sizeof(TextBuffer), "After write\n");
HAL_UART_Transmit(&huart4, (uint8_t*)TextBuffer, strlen(TextBuffer), 0xFFFFFFFF);


preservedVariable++;

tim3stat=false;
}
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */

}

 

/* I2C1 init function */
static void MX_I2C1_Init(void)
{

hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00201D2C;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}

/**Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}

/**Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}

}

I'm trying to save the value of `preservedVariable` in the external EEPROM. TIM3 is set to be repeated every 3 seconds. Could somebody please help me to understand what am I doing wrong?

Outcomes