cancel
Showing results for 
Search instead for 
Did you mean: 

Problem writing string to emulated Eeprom

jlourencao
Associate II

Can anyone explain to me what is wrong in my code?

Microcontroller: STM32C031K6T6

I'm trying to make an interface so that the user can change the name of their environment in real time, my idea and what I tried to write is something that holds the previous strings (which may already be edited) in RAM, makes the modifications and then then write in flash again. Currently my code is like this, it shows the environments ("AMBIENTE  01...24"), I can edit the name of the string, it "saves" when i call Grava();, but when I turn my board off and on the changes do not continue... 

I tried to copy the txtL strings to b_txtL using memcpy, and strncpy at the beginning of main();, but when i do this my my display goes "crazy" showing the strings "AMBIENTE ..." all broken in line 1 and 2

Note: I can't debug and at the same time see the changes that happen on the display because the SWCLK pin was used for a display pin, I had to implement a code that erased the memory after holding down some buttons to be able to record another code, workaround ...


 

 

const char txtL[][17] = {
    "  AMBIENTE L01  ", "  AMBIENTE L02  ", "  AMBIENTE L03  ",
    "  AMBIENTE L04  ", "  AMBIENTE L05  ", "  AMBIENTE L06  ",
    "  AMBIENTE L07  ", "  AMBIENTE L08  ", "  AMBIENTE L09  ",
    "  AMBIENTE L10  ", "  AMBIENTE L11  ", "  AMBIENTE L12  ",
    "  AMBIENTE L13  ", "  AMBIENTE L14  ", "  AMBIENTE L15  ",
    "  AMBIENTE L16  ", "  AMBIENTE L17  ", "  AMBIENTE L18  ",
    "  AMBIENTE L19  ", "  AMBIENTE L20  ", "  AMBIENTE L21  ",
    "  AMBIENTE L22  ", "  AMBIENTE L23  ", "  AMBIENTE L24  ",
    "   ENGFOX 24L   "
}; // default flash text
char b_txtL[26][17]; //BUFFER

int main{
//lcd and gpios inits
EEPROM_INIT();
lerEeprom();

//button config and enters the prog
Prog();

//test to see if saved something
lcd_set_cursor(0, 0);
lcd_write_string2((const char*)txtL[0]);
lcd_set_cursor(0, 1);
lcd_write_string2((const char*)b_txtL[15]);

// Prog func
/* I'm using a eeprom_write function to write flags of 0 or 1, due to the limitation of my microcontroller I can only use DOUBLEWORD, which ends up recording a flag in 32 bits, and the next 32 bits are empty */

 while (loop < 26) {
    	DisplayLaco(loop);
    	HAL_Delay(60);

    	if (HAL_GPIO_ReadPin(GPIOA, SW1_Pin) == GPIO_PIN_RESET)
    	{
    		HAL_Delay(200);

    		// Verifica o estado atual dos bits
    		int re_bit = (ure.re_all[loop / 8] & (1 << (loop % 8))) ? 1 : 0;
    		int rfl_bit = (urfl.rfl_all[loop / 8] & (1 << (loop % 8))) ? 1 : 0;

    		// Alterna entre as combinações S N, N S, N N, S S
    		if (re_bit && !rfl_bit)
    		{
    			// Caso atual seja S N -> Muda para N S
    			ure.re_all[loop / 8] &= ~(1 << (loop % 8));  // Desativa o bit em re_all
    			urfl.rfl_all[loop / 8] |= (1 << (loop % 8)); // Ativa o bit em rfl_all
    		}
    		else if (!re_bit && rfl_bit)
    		{
    			// Caso atual seja N S -> Muda para N N
    			ure.re_all[loop / 8] &= ~(1 << (loop % 8));  // Desativa o bit em re_all
    			urfl.rfl_all[loop / 8] &= ~(1 << (loop % 8)); // Desativa o bit em rfl_all
    		}
    		else if (!re_bit && !rfl_bit)
    		{
    			// Caso atual seja N N -> Muda para S S
    			ure.re_all[loop / 8] |= (1 << (loop % 8));   // Ativa o bit em re_all
    			urfl.rfl_all[loop / 8] |= (1 << (loop % 8)); // Ativa o bit em rfl_all
    		}
    		else
    		{
    			// Caso atual seja S S -> Muda para S N
    			ure.re_all[loop / 8] |= (1 << (loop % 8));   // Ativa o bit em re_all
    			urfl.rfl_all[loop / 8] &= ~(1 << (loop % 8)); // Desativa o bit em rfl_all
    		}

    		DisplayLaco(loop);  // Atualiza o display
    	}

            if (HAL_GPIO_ReadPin(GPIOA, SW2_Pin) == GPIO_PIN_RESET) {
                HAL_Delay(200);
                uoff.off_all[loop / 8] ^= (1 << (loop % 8));
                DisplayLaco(loop);
            }

            if (HAL_GPIO_ReadPin(GPIOA, SW3_Pin) == GPIO_PIN_RESET) {
                HAL_Delay(200);
                Conf_txt(loop);
                lcd_display_control(true, false, false);
                DisplayLaco(loop);
                loop++;
            }
        }

        dcBKL_ch2(200);
    }

//Display func (Maybe the trouble is here, idk)

void DisplayLaco(int loop)
{
    // Exibe informações sobre o laço atual e o nome correspondente
    char nomeL[20];
    snprintf(nomeL, sizeof(nomeL), "L%02d:", loop + 1);

    lcd_set_cursor(0, 0);
    lcd_write_string(nomeL);
    lcd_write_string((uoff.off_all[loop / 8] & (1 << (loop % 8))) ? "S " : "N ");
    lcd_write_string((ure.re_all[loop / 8] & (1 << (loop % 8))) ? "RE:S " : "RE:N ");
    lcd_write_string((urfl.rfl_all[loop / 8] & (1 << (loop % 8))) ? "RFL:S" : "RFL:N");

    // Exibe o nome do ambiente correspondente (da RAM)
    lcd_set_cursor(0, 1);
    // Copiar as strings de b_txtL para txtL (presumindo que b_txtL foi modificado)
    lcd_write_string(b_txtL[loop]);  // `b_txtL[loop]` já deve estar em `char[]`

}
// Conf_txt func, it's a bit buggy, I'm trying to solve it...

void Conf_txt(uint16_t loop)
{
    // Permite a edição em tempo real do nome selecionado em b_txtL
    bool edit = true;
    // Posição do caractere dentro do nome
    uint8_t pressCounter = 0;
    uint8_t col = 0;
    // Exibe o nome inicial na LCD
    lcd_write_string2((const char*)b_txtL[loop]);
    lcd_set_cursor(col, 1);  // Coloca o cursor na posição inicial

    while (edit)
    {
        lcd_display_control(true, true, true);
        lcd_set_cursor(col, 1);  // Atualiza a posição do cursor

        bool SW3 = (HAL_GPIO_ReadPin(GPIOA, SW3_Pin) == GPIO_PIN_RESET);

        // Pressão longa do SW3 para sair do modo de edição
        if (SW3)
        {
            pressCounter++;  // Incrementa o contador
            if (pressCounter >= 15)  // 3 segundos (ajuste conforme necessário)
            {
                edit = false;
                lcd_display_control(true, false, false);
                Grava();
                return;
            }
        }
        else
        {
            pressCounter = 0;  // Resetando o contador após uma ação
            col++;  // Avança para a próxima coluna
            lcd_set_cursor(col, 1);
            if (col >= 16)
            {
                col = 0;
            }
        }

        // Controle de incremento e decremento do caractere na posição atual
        if (HAL_GPIO_ReadPin(GPIOA, SW1_Pin) == GPIO_PIN_RESET)
        {
            HAL_Delay(200);
            b_txtL[loop][col]++;
            if (b_txtL[loop][col] > 0x5A) b_txtL[loop][col] = 0x30;  // "Z" -> "0"
            else if (b_txtL[loop][col] < 0x30) b_txtL[loop][col] = 0x41;  // " " -> "A"
            else if (b_txtL[loop][col] > 0x39 && b_txtL[loop][col] < 0x41) b_txtL[loop][col] = 0x20;  // "9" -> " "
            lcd_write_string2((const char*)b_txtL[loop]);   // Atualiza o caractere na posição do cursor
        }

        if (HAL_GPIO_ReadPin(GPIOA, SW2_Pin) == GPIO_PIN_RESET)
        {
            HAL_Delay(200);
            b_txtL[loop][col]--;
            if (b_txtL[loop][col] < 0x20) b_txtL[loop][col] = 0x39;  // " " -> "9"
            else if (b_txtL[loop][col] < 0x30) b_txtL[loop][col] = 0x5A;  // "0" -> "Z"
            else if (b_txtL[loop][col] > 0x39 && b_txtL[loop][col] < 0x41) b_txtL[loop][col] = 0x20;  // "A" -> " "
            lcd_write_string2((const char*)b_txtL[loop]);  // Atualiza o caractere na posição do cursor
        }

        HAL_Delay(200);
        }
    }

// Then, after i call grava(); function to write the changes in the eeprom

for (int i = 0; i < 26; i++) // i is my ID
    {
    	EEPROM_WRITE_STRING(i, b_txtL[i]);
    }

// EEPROM write stirng. 
void EEPROM_WRITE_STRING(uint16_t id, const char* c)
{

    HAL_Delay(10); // Pode ser ajustado conforme necessário
    HAL_FLASH_Unlock();  // Desbloqueia a memória FLASH para gravação

    uint32_t address = ACTIVE_PAGE;  // Começa no endereço da última gravação

    // Verifica o comprimento da string
    int str_len = strlen(c);
    if (str_len > 17) str_len = 17;  // Limita o comprimento a 17 caracteres (tamanho máximo da string)

    // Garantir que o endereço está alinhado a 8 bytes
    if (address % 8 != 0)
    {
        address += 8 - (address % 8);  // Ajuste de alinhamento
    }

    // Grava a string na Flash em blocos de 8 bytes
    for (int offset = 0; offset < str_len; offset += 8)
    {
        uint64_t data_to_write = 0;

        // Preenche os próximos 8 bytes (ou menos, se a string terminar antes)
        for (int i = 0; i < 8; i++)
        {
            if (offset + i < str_len) {
                data_to_write |= ((uint64_t)c[offset + i]) << (i * 8);
            }
        }

        // Grava os dados na memória FLASH
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data_to_write);
        address += 8;  // Avança para o próximo endereço
    }


    if (address >= (ACTIVE_PAGE + PAGE_SIZE - sizeof(EEPROM)))
    {EEPROM_SWAP();}

    HAL_FLASH_Lock();  // Bloqueia a memória FLASH após a gravação
}




void EEPROM_READ_STRING(uint16_t id, char* c)
{
    uint32_t address = ACTIVE_PAGE + (id * sizeof(EEPROM));  // Endereço baseado no ID
    uint64_t data_read = 0;

    // Lê os dados da memória FLASH em blocos de 8 bytes
    while (address < (ACTIVE_PAGE + PAGE_SIZE))
    {
    	EEPROM* entry = (EEPROM*)address;

    	if (entry->id == id)
    	{
    		for (int offset = 0; offset < 17; offset += 16)
    		{
    			data_read = *(volatile uint64_t*)address;

    			// Copia os dados lidos de volta para a string
    			memcpy(&c[offset], &data_read, (offset + 8 <= 17) ? 8 : (17 - offset));

    			address += 8;  // Avança para o próximo endereço
    		}
    	}
    	address += sizeof(EEPROM);
    }

}



 

 



12 REPLIES 12
LCE
Principal

It was actually @Andrew Neil who said first that flash must be erased before writing, so maybe mark his answer as solution.

Although I guess "in the end it doesn't really matter", as who sang? ;)

syedhashmiraza
Associate II

hello iam using srm32f429i-disc1 microcontroller and i want refrence code for emulated eeprom 

@syedhashmiraza you already have your own thread on this:

https://community.st.com/t5/stm32-mcus-products/use-stm32f4-flash-for-non-volatile-data-storage-eeprom/td-p/743291

This thread is about a different, much newer chip - not relevant to yours.