Skip to main content
Visitor II
July 26, 2024
Solved

uint8_t Values Are Not Changing

  • July 26, 2024
  • 1 reply
  • 2969 views

 

I want to download and use firmware (FW) to DDR3. Since DDR is initially disabled, the firmware to activate DDR and the main FW project are separate, and the download procedure is as follows:

  1. First, run the DDR activation FW to enable DDR.
  2. Download the main FW to DDR and enter debug mode. (The main FW does not perform MPU initialization during download because the debugger has cleared the monitor reset.)

 

For reference, the MPU is the STM32MP131FAE7, and the DDR is the K4B4G1646E.

I have successfully enabled DDR and modified the linker script of the main FW to download FW to DDR (base address: 0xC0000000). However, there is an issue. Among various possible problems, the most challenging one to solve right now is that the uint8_t variables are not changing as expected.

Even when assigning values to uint8_t variables like:

 

uint8_t val1 = 10;
uint8_t val2 = 20;
uint8_t val3 = 30;
uint8_t val4 = 40;

they do not change properly. There are no such issues with uint16_t or uint32_t variables.

Here is a portion of my DDR activation FW code. I wrote it with reference to examples from the STM32MP135C-DK board, and there are almost no differences.

 

 

 /*Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C2_Init();
MX_I2C3_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */

pmicInit();
pmic_InitRegulators();

/* USER CODE BEGIN 2 */
/*##-1- Enable MCE ####################*/
__HAL_RCC_MCE_CLK_ENABLE();

/*##-2- TZC configuration ####################*/
__HAL_RCC_TZC_CLK_ENABLE();

/* Configure TZC to allow DDR Region0 R/W non-secure for all IDs */
TZC->GATE_KEEPER = 0;
TZC->REG_ID_ACCESSO = 0xFFFFFFFF; // Allow DDR Region0 R/W non-secure for all IDs
TZC->REG_ATTRIBUTESO = 0xC0000001;
TZC->GATE_KEEPER |= 1; // Enable the access in secure Mode // filter 0 request close

/*##-3- Enable ETZPC & BACKUP SRAM for security ####################*/
__HAL_RCC_ETZPC_CLK_ENABLE();
__HAL_RCC_BKPSRAM_CLK_ENABLE();

/*##-4- Unlock debugger ####################*/
BSEC->BSEC_DENABLE = 0x47f;

/*##-5- Init DDR ####################*/
hddr.wakeup_from_standby = false;
hddr.self_refresh = false;
hddr.zdata = 0;
hddr.clear_bkp = false;

if (HAL_DDR_Init(&hddr) != HAL_OK)
{
 Error_Handler();
}

/*##-6- Check DDR Write/Read ####################*/
*p = DDR_PATTERN;

if (*p != DDR_PATTERN)
{
 Error_Handler();
}

/* Write and read operations */
WRITE_REG(*(volatile uint8_t *)0xC0000004, 0xAA);
WRITE_REG(*(volatile uint8_t *)0xC0000005, 0xBB);
WRITE_REG(*(volatile uint8_t *)0xC0000006, 0xCC);
WRITE_REG(*(volatile uint8_t *)0xC0000007, 0xDD);

uint8_t ret1 = READ_REG(*(volatile uint8_t *)0xC0000004);
uint8_t ret2 = READ_REG(*(volatile uint8_t *)0xC0000005);
uint8_t ret3 = READ_REG(*(volatile uint8_t *)0xC0000006);
uint8_t ret4 = READ_REG(*(volatile uint8_t *)0xC0000007);

 

 

The code below works correctly in the DDR activation FW, but in the main FW running on DDR, it is not able to read the values correctly:

WRITE_REG(*(volatile uint8_t *)0xC0000004, 0xAA);
WRITE_REG(*(volatile uint8_t *)0xC0000005, 0xBB);
WRITE_REG(*(volatile uint8_t *)0xC0000006, 0xCC);
WRITE_REG(*(volatile uint8_t *)0xC0000007, 0xDD);

uint8_t ret1 = READ_REG(*(volatile uint8_t *)0xC0000004);
uint8_t ret2 = READ_REG(*(volatile uint8_t *)0xC0000005);
uint8_t ret3 = READ_REG(*(volatile uint8_t *)0xC0000006);
uint8_t ret4 = READ_REG(*(volatile uint8_t *)0xC0000007);

I cannot identify the cause of the issue and need assistance.

Thank you for your help

    This topic has been closed for replies.
    Best answer by PatrickF

    Hi @Stnoobs 

    on DDR memories, you have some freedom to swap bit within a byte and swapping bytes. This is to ease PCB routing to achieve better signal integrity (e.g. avoid some vias).

    This is described in various documents linked above.

    On our board example, we do both. This explain why you see DQS0/DQM0 together with DQ0-7, which is the lower byte of STM32MP13 connected the the DDR3L upper byte.

    As general, a memory does not care about bit or byte number, you simply read a bit value where you have written it. There is some exceptions when there is 'registers' using DQ inside the memory (e.g. LPDDRx)

    As spotted in my first reply, your schematics confirm there is a mistake around DQM/DQS. Your DM0/1 are swapped (i.e. if DQ0-7 and DQS0 are connected to lower byte of the DDR, then DQM0 must be also going to lower byte).

    PatrickF_1-1722495958310.png

     

    This explain your issue around byte write (as the byte 'mask' does not mask the right byte on the memory bus).

    There is no solution than reworking your PCB.

    Regards.

    1 reply

    Technical Moderator
    July 26, 2024

    Hi,

    Maybe look at some PCB HW mixup on DDR_DQM/DQS lines Vs DQ.

    Regards.

    StnoobsAuthor
    Visitor II
    July 26, 2024


    If there were a hardware connection issue with the DDR, shouldn't the DDR Init FW's DDR Read/Write test routine fail?

    I have confirmed that all Read/Write operations in the DDR are functioning correctly within the DDR Init FW, and subsequently, I have downloaded the Main FW to the DDR

    Technical Moderator
    July 26, 2024

    Hi,

    I think DDR tests are done using only 32-bits access and/or with cache enabled (as goal is to check timings, not wiring), which might mean only 32-bits access are done to the DDR (i.e. no byte mask differentiation).

    We have already seen this kind of mistake on some other customers with similar behavior.

    A quick check on your schematics should confirm or not this hypothesis.

    Regards.