AnsweredAssumed Answered

LCD frame buffer in HyperRAM

Question asked by Peter Janco on May 15, 2019
Latest reply on Jun 25, 2019 by Hui_Ma

Hi,

I am using my own design with IMXRT1062. I have connected S70KS1281 hyperram chip to FLEXSPI2 interface. All initialization of hyperram is based on AN12239SW example project.

 

Hyperram is working, I am able to do read/write test on address range 0x70000000 - 0x71000000 without any errors.  But I have problem with LCD frame buffer located in hyperram address range. If I am displaying static picture on the display, it is working well. But if I draw some points and lines to frame area, Image on the display is shifted to the side. I tried to change frame buffer location from hyperram to OC ram, and inside OC ram, the same source code is working well.


I think this is somehow related to switching between read and write operations on flexspi. I am doing a write operations inside main loop. And LCD driver is doing DMA read operations on backgroud.

 

My function for drawing pixels in main loop is looking like this:

#define LCD_FRAME 0x70800000
void Point(uint16_t color, uint16_t x, uint16_t y)
{
uint32_t addr = LCD_FRAME + (2 * x) + (y * 800 * 2);
*(uint16_t*)addr = color;
}

 

And I have this result on display:

 

Then I modified draw function like this:

#define LCD_FRAME 0x70800000
void Point(uint16_t color, uint16_t x, uint16_t y)
{
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI2))
{
}
uint32_t addr = LCD_FRAME + (2 * x) + (y * 800 * 2);
*(uint16_t*)addr = color;
}

 

And it solved the problem:

 

But I think this is not good solution. I think DMA controller should take care about this conflicts automatically...

 

This is my MPU configuration, maybe there is a problem, I donk know. I tried all permutations of MPU settings without luck. Region 8 is hyperram nocache area used for frame buffer:

/* MPU configuration. */
void BOARD_ConfigMPU(void)
{
/* Disable I cache and D cache */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
}
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
}

/* Disable MPU */
ARM_MPU_Disable();

/* MPU configure:
* Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable,
* SubRegionDisable, Size)
* API in core_cm7.h.
* param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches
* disabled.
* param AccessPermission Data access permissions, allows you to configure read/write access for User and
* Privileged mode.
* Use MACROS defined in core_cm7.h:
* ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO
* Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes.
* TypeExtField IsShareable IsCacheable IsBufferable Memory Attribtue Shareability Cache
* 0 x 0 0 Strongly Ordered shareable
* 0 x 0 1 Device shareable
* 0 0 1 0 Normal not shareable Outer and inner write
* through no write allocate
* 0 0 1 1 Normal not shareable Outer and inner write
* back no write allocate
* 0 1 1 0 Normal shareable Outer and inner write
* through no write allocate
* 0 1 1 1 Normal shareable Outer and inner write
* back no write allocate
* 1 0 0 0 Normal not shareable outer and inner
* noncache
* 1 1 0 0 Normal shareable outer and inner
* noncache
* 1 0 1 1 Normal not shareable outer and inner write
* back write/read acllocate
* 1 1 1 1 Normal shareable outer and inner write
* back write/read acllocate
* 2 x 0 0 Device not shareable
* Above are normal use settings, if your want to see more details or want to config different inner/outter cache
* policy.
* please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide <dui0646b_cortex_m7_dgug.pdf>
* param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled.
* param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in
* core_cm7.h.
*/

/* Region 0 setting: Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(0, 0xC0000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);

/* Region 1 setting: Memory with Normal type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(1, 0x70000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_1GB);

/* Region 2 setting */
#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
/* Setting Memory with Normal type, not shareable, outer/inner write back. */
MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_8MB);
#else
/* Setting Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_8MB);
#endif

/* Region 3 setting: Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(3, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);

/* Region 4 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);

/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(5, 0x20000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);

/* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(6, 0x20200000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_512KB);

/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(7, 0x20280000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);

/* Region 8 setting: Memory with Normal type, noncache, */
MPU->RBAR = ARM_MPU_RBAR(8, 0x70800000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_8MB);

/* Enable MPU */
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);

/* Enable I cache and D cache */
SCB_EnableDCache();
SCB_EnableICache();
}

 

 

Does anyone understand this problem? It is possible to use hyperram for LCD frame buffer?

Outcomes