cancel
Showing results for 
Search instead for 
Did you mean: 

uint8_t Values Are Not Changing

Stnoobs
Associate II

 

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

12 REPLIES 12

Thank you for your response.

I have some questions regarding the "STM32MP13x Series DDR memory routing guidelines examples" you mentioned in your previous response. I apologize for not reviewing the materials more carefully.

 

Could you please explain why the Data Bit (DQ Pin) connections of the DDR (MT41K512M16VRP) need to be connected as shown in the example rather than in a 1:1 manner (e.g., DDR DQ0 to DQ0)? Is there a specific reason for this?

 Like 

   DDR DQ8   ↔ DQ0

   DDR DQ15 ↔ DQ1

   DDR DQ13   ↔ DQ2

   DDR DQ12 ↔ DQ3

   DDR DQ9   ↔ DQ4

   DDR DQ11 ↔ DQ5

...

 

Additionally, why are the DQS0 and DQM0 of the STM32MP13 located next to the DQ07 pins, while the DQS0 and DQM0 of the DDR are positioned next to the DQ815 pins? Should the DQS0/1 and DQM0/1 of the STM32MP135FAE7 and the DDR be connected in a crossed manner?

Stnoobs_0-1722494932970.png

 

Furthermore, we have attached our DDR connection schematic for your reference.

Stnoobs_1-1722494964026.png

 

 

Thank you very much for your assistance.

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.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Thank you.

After modifying the circuit according to your advice and checking it again, the values are written correctly now.