cancel
Showing results for 
Search instead for 
Did you mean: 

FSMC LCD display migrating from F412 to F746 doesn't work

SWood.4
Associate III

I have a LCD display working on a nucleo F412 using FSMC. I'm trying to move to a nucleo F746. I have moved the code and includes from the 412 to the 746 project and connected the display to the correct pins for the 746. The 746 pin out is a little different than the 412 for the default connections. I have the same clock speeds and settings. I compared the FMC init function line by line between the two and all the setting match, but I can't get the display to work using the 746. Using a logic analyzer and comparing the two boards running the same code I can see there are differences on the FMC A18,FMC_NE1,FMC_NWE and FMC_NOE pins. The logic analyzer is sampling at 24MHZ. I've moved the display jumpers for the display back to the F412 and it works, back to F746 making sure to adjust for the differences in the pins a few times now. Any idea's where or why the display works on the F412 but the same settings, clock speeds and code won't work on the F746?

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions

It's took a bit but it's working now. I got a new probe so I can see what is going to the LCD and decode the values. About every third write to the LCD was a bad value that would write immediately before or after a good value. It would do the same with the memory swap and writing to 0xC000'0000 and the default 0x6000'0000. I left the memory swap and code so it would write to 0xC000'0000. I thought maybe the Nucleo board had a solder jumper, or a UART/Debug or some other signal interfering. So I used the same code and made sure I could just send a 0x00, 0x01, 0x02, 0x04.. 0xF0 to the LCD. That was all good. I picked about 5 or 6 real commands for the LCD like 0x28, 0xC5 and I could send those out one at a time when debugging, but when running at normal speeds I'd get random values again. I was pretty convinced that it must need more address setup time , data setup time, buss turn around etc. I tried enabling the Extended mode values and still about every third value was incorrect. I disabled the Extended mode, put the bus turn around time, data setup time and address setup time back to the previous values and started adding 1ms delays between commands and the display started working. No more random commands were showing up. I started removing the delays to isolate where things went bad, but ended up taking all the delays out, speeding up the set up times etc. and the display kept working. I commented out the memory swap, changed the code to write to 0x6000'0000, about every third value is incorrect again. I've confirmed a few times now the memory swap is needed and without it bad commands show up. I'm not sure why things changed and worked like it should at that particular point, It seems like the MCU was holding a grudge from 4 days ago when I wrote an incorrect value to the SYSCFG_MEMRMP. :) Thanks for letting me know about this setting and the rest of the help.

View solution in original post

10 REPLIES 10

You need the memory area, into which the LCD is mapped, set as Device in MPU. There may be a mapping swap bit achieving this without setting MPU, don't have the RM at hand now.

JW​

Are you talking about the SRAM Memory bank address for the FMC/FSMC? If so it looks like both are the same. The address starts at 0x6000 0000. Let me know if you're referring to a different setting. Thanks

> If so it looks like both are the same. The address starts at 0x6000 0000.

There are mountains of differences between the Cortex-M4 and Cortex-M7 core. The latter for example performs speculative accesses to memory areas tagged as Normal (the former does not).

As I've said, use SYSCFG_MEMRMP.SWP_FMC to map the SRAM memory bank to 0xC000'0000 (which is by default tagged Device), or use the MPU to tag the 0x6000'0000 area as Device.

There may be some other problem in your case, but this one is certainly a problem too, so start here.

JW

Thanks for the quick reply. In the stm32f7xx_hal.c file I found :

/**

 * @brief Enables the FMC Memory Mapping Swapping.

 *  

 * @note  SDRAM is accessible at 0x60000000 

 *     and NOR/RAM is accessible at 0xC0000000  

 *

 * @retval None

 */

void HAL_EnableFMCMemorySwapping(void)

{

 SYSCFG->MEMRMP |= SYSCFG_MEMRMP_SWP_FMC_0;

}

I changed SYSCFG_MEMRMP_SWP_FMC_0 to SYSCFG_MEMRMP_SWP_FMC_1

After reprogramming I didn't see any changes on the LCD. So I called HAL_EnableFMCMemorySwapping() in the first line of MAIN, this seems to stop the MCU completely. Changing back to SYSCFG_MEMRMP_SWP_FMC_0 and calling the function from main still stops the MCU. Removing the call to the memory swap the MCU is running again with out an LCD. So I'm guessing I need to set the value somewhere else in code so it doesn't stop the MCU?

Thanks

> I changed SYSCFG_MEMRMP_SWP_FMC_0 to SYSCFG_MEMRMP_SWP_FMC_1

Why? Have you checked what values are valid for SYSCFG_MEMRMP.SWP_FMC in the RM?

> Changing back to SYSCFG_MEMRMP_SWP_FMC_0 and calling the function from main still stops the MCU.

What is "stops MCU"? Describe what the mcu exactly does, use debugger to find out.

Do you understand what the remap does, i.e. that the FMC SRAM bank is now at a different address?

JW

Thanks for the reply.

Using Debug after calling HAL_EnableFMCMemorySwapping() and returning to main the code jumps to a hard fault handler when I start calling LCD functions.

From your previous reply I understood that I should use SYSCFG_MEMRMP.SWP_FMC to swap SDRAM at 0x60000000 with NOR/RAM 0xC0000000.

From the RM:

Bits 11:10 SWP_FMC[1:0]: FMC memory mapping swap

00: No FMC memory mapping swapping

01: NOR/RAM and SDRAM memory mapping swapped

"Do I understand what remap does", well, I know what the RM says, but It's new territory for me :) The code that I have for the LCD is writing to address 0x60000000, so I thought that was the address you were saying I should have for the NOR/RAM not the SDRAM. Searching the includes I found the HAL_EnableFMCMemorySwapping() and the two values defined for it SYSCFG_MEMRMP_SWP_FMC_0 and SYSCFG_MEMRMP_SWP_FMC_1. I thought the FMC_0 was the default value used and FMC_1 enabled the memory swap. It looks like FMC_0 would toggle the correct bit in SYSCFG_MEMRMP. It's possible I'm misunderstanding your instructions. My experience is with "less powerful" and "less flexible" MCU's so this topic is new to me.

#define SYSCFG_MEMRMP_SWP_FMC_0     (0x1UL << SYSCFG_MEMRMP_SWP_FMC_Pos)  /*!< 0x00000400 */

#define SYSCFG_MEMRMP_SWP_FMC_1     (0x2UL << SYSCFG_MEMRMP_SWP_FMC_Pos)  /*!< 0x00000800 */

Let me know if I got on the wrong path or if I'm not calling the HAL_EnableFMCMemorySwapping() function in the correct way/time/location. I thought I read that memory swap can be called in code. Using FMC_1 and FMC_0 both result in hard faults when I call memory swap from main.

Thanks

I started a new project and only enabled the FMC for the F746 to make sure I didn't have some other interrupt or code getting in the way. I maxed out clock setup times to slow things down also. I'm not sure why NE1 signal would change from a toggle during communication at faster speeds to staying low during communication at a slower speed. The LCD still doesn't work when connect to the F746. I ordered a new probe with 16 channels so I can capture all the signals and timing and decode the data. Some screen shots below for the same command. Let me know if you have anything I should look at.

Thanks

0693W00000QO7FeQAL.png0693W00000QO7GIQA1.png0693W00000QO7GNQA1.png

> My experience is with "less powerful" and "less flexible" MCU's so this topic is new to me.

Setting bitfields to a certain value is surely not MCU-specific knowledge. You can also read out and check the register's value in debugger.

> The code that I have for the LCD is writing to address 0x60000000,

After setting the swap, LCD moves to 0xC000'0000, so you have to change the code accordingly.

JW

It's took a bit but it's working now. I got a new probe so I can see what is going to the LCD and decode the values. About every third write to the LCD was a bad value that would write immediately before or after a good value. It would do the same with the memory swap and writing to 0xC000'0000 and the default 0x6000'0000. I left the memory swap and code so it would write to 0xC000'0000. I thought maybe the Nucleo board had a solder jumper, or a UART/Debug or some other signal interfering. So I used the same code and made sure I could just send a 0x00, 0x01, 0x02, 0x04.. 0xF0 to the LCD. That was all good. I picked about 5 or 6 real commands for the LCD like 0x28, 0xC5 and I could send those out one at a time when debugging, but when running at normal speeds I'd get random values again. I was pretty convinced that it must need more address setup time , data setup time, buss turn around etc. I tried enabling the Extended mode values and still about every third value was incorrect. I disabled the Extended mode, put the bus turn around time, data setup time and address setup time back to the previous values and started adding 1ms delays between commands and the display started working. No more random commands were showing up. I started removing the delays to isolate where things went bad, but ended up taking all the delays out, speeding up the set up times etc. and the display kept working. I commented out the memory swap, changed the code to write to 0x6000'0000, about every third value is incorrect again. I've confirmed a few times now the memory swap is needed and without it bad commands show up. I'm not sure why things changed and worked like it should at that particular point, It seems like the MCU was holding a grudge from 4 days ago when I wrote an incorrect value to the SYSCFG_MEMRMP. :) Thanks for letting me know about this setting and the rest of the help.