I Have not looked at your link yet but, i will but before i do I can add something to this that I have had issues with so my pain might not be yours.
1. I have found most examples are broken when used in later/modern versions of compilers for one reason or another (stm32 code pre 8 works but after 9 you will have cube lib issues ) and keil is just to variable between mcu's and longer learning curve for some like me.
2. FSMC on 407_vet requires all the correct steps are taken , clocks , gpio config, fsmc (this include which pins are ws/wr/rd/cs)
3. lots of FSMC code out there but non fully explain the CS pins and memory read/write in usage or config(the will example their usage but not say another one to give context)
4. if you want to us STM then i suggest vscode platformio , it supports cubemx, arduino, cmsis and more, the reason i use it often is i can import sample code from many source libs type (cubemx,cmsis) into a fresh project easily and also use library's easily (theres some trick to that but i can explain and demonstrate )
5. between different HAL libs (cubemx, arduino, cmsis) the hardware is often reference in totally ways and often setup and treated as different groups , where cmsis will setup a peripheral (lets say FSMC ) as just the FSMC hardware (no gpio settings, no clock setup yet) the ST CUBEMX will setup clocks, gpio, irq's, dma and then FSMC in one call (HAL_FSMC_Init()
6. when starting out with stm32 it is worth having both platformio and stmcube mx /stm cube programmer installed, the reason is you can use the GUI of stm32 cubemx to configure your MCU/CPU and export that project, then with a few simple changes to a platformio.ini file you can have a instant populated project with peripherals configured , the cubemx IDE also has PDF's and pinouts to the chips so i will often use it just for that and do the code in platformio , i use it because its got plugins that allow me to follow the code easier to the HAL_LL or hall low level and then i can create a bare metal version from there.
Now onto help to configure the FSMC, as mentioned you need GPIO, clocks, FSMC itself ,dma and irq's with the latter two not fully required for initial function (and give no benefit in the start)
First lets cover configuring the actual devices we are going to use , this hardware is the default pins that most fsmc project uses the default except the "CS , read/write/command"
that would be
// TFT connector uses FSMC pins
// D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15
// PD14 PD15 PD0 PD1 PE7 PE8 PE9 PE10 PE11 PE12 PE13 PE14 PE15 PD8 PD9 PD10
with our bank addressing (where you read/write to lcd)
at
#define FMC_REGION ((uint32_t)0x60000000) // Bank1 FMC NOR/PSRAM
#define CommandAccess FMC_REGION //write to this address as a command
//#define DataAccess (FMC_REGION + 0x20000) // FSMC_A16
#define DataAccess (FMC_REGION + 0x40000) // FSMC_A17 //write to this address to data
now you will note we have the above #define for the DATA portion of the LCD/FSMC , now just because we define it there does not mean we have configured the hardware fully,
in the following list we define the setup of the FSMC, which is NE1(_CS), FSMC_A17 (_RS), FSMC_NWE(_wr) , FSMC_NOE (_rd) pins,
in my example they are :-
** note code, just a list for remembering **
_cs = PD7; // FSMC_NE1 chip select when low
_rs = PD12; // FSMC_A17 //Use PD11 for FSMC_A16 , rs is also known as REGISTER_SELECT and switches between command mode/data mode , when low mode is command mode
_rst = 0; // not available, driven from NRST
_wr = PD5; // FSMC_NWE
_rd = PD4; // FSMC_NOE
Actual values used in code
#define PD_AFR0_MASK 0xF0FF00FF
#define PD_AFR0_FSMC 0xC0CC0CCC
#define PD_AFR1_MASK 0xFFF00FFF
#define PD_AFR1_FSMC 0xCC0C0CCC
// config for FSMC_A17 as command/data pin
#define PD_MODE_MASK 0xFC3FCF0F // all FMSC MODE bits
#define PD_MODE_FSMC 0xA22A8A2A // FMSC MODE values 10 alternate function
//#define PD_OSPD_FSMC 0x54154505 // FMSC OSPEED values 01 10MHz
#define PD_OSPD_FSMC 0xf33fcf3f // FMSC OSPEED values 01 10MHz
// | | |
#define PE_AFR0_MASK 0xF0000000
#define PE_AFR0_FSMC 0xC0000000
#define PE_AFR1_MASK 0xFFFFFFFF
#define PE_AFR1_FSMC 0xCCCCCCCC
// | | |
#define PE_MODE_MASK 0xFFFFC000 // all FMSC MODE bits
#define PE_MODE_FSMC 0xAAAA8000 // FMSC MODE values 10 alternate function
#define PE_OSPD_FSMC 0x55554000 // FMSC OSPEED values 01 10MHz
#define ADDSET 10 // (ADDSET+1)*6ns = CS to RW
#define DATAST 15 // (DATAST+1)*6ns = RW length
and usage in setup function.
void GxIO_STM32F407VxT6_FSMC::init()
{
RCC->AHB1ENR |= 0x00000078; // enable GPIOD, GPIOE, GPIOF and GPIOG interface clock
volatile uint32_t t = RCC->AHB1ENR; // delay
GPIOD->AFR[0] = ( GPIOD->AFR[0] & ~PD_AFR0_MASK) | PD_AFR0_FSMC;
GPIOD->AFR[1] = ( GPIOD->AFR[1] & ~PD_AFR1_MASK) | PD_AFR1_FSMC;
GPIOD->MODER = ( GPIOD->MODER & ~PD_MODE_MASK) | PD_MODE_FSMC;
GPIOD->OSPEEDR = ( GPIOD->OSPEEDR & ~PD_MODE_MASK) | PD_OSPD_FSMC;
GPIOD->OTYPER &= ~PD_MODE_MASK;
GPIOD->PUPDR &= ~PD_MODE_MASK;
GPIOE->AFR[0] = (GPIOE->AFR[0] & ~PE_AFR0_MASK) | PE_AFR0_FSMC;
GPIOE->AFR[1] = (GPIOE->AFR[1] & ~PE_AFR1_MASK) | PE_AFR1_FSMC;
GPIOE->MODER = (GPIOE->MODER & ~PE_MODE_MASK) | PE_MODE_FSMC;
GPIOE->OSPEEDR = (GPIOE->OSPEEDR & ~PE_MODE_MASK) | PE_OSPD_FSMC;
GPIOE->OTYPER &= ~PE_MODE_MASK;
GPIOE->PUPDR &= ~PE_MODE_MASK;
RCC->AHB3ENR |= 0x00000001;
t = RCC->AHB1ENR; // delay
(void)(t);
FSMC_Bank1->BTCR[0] = 0x00001091;
FSMC_Bank1->BTCR[1] = (DATAST << 8) | ADDSET;
}
as to what MODER, OSPEEDR etc mean you can find that in the 407_vet manual available via cubemx or stm32 web site , but the short of them are they are the registers for each port (GPIOD,GPIOE etc) and the binary bits configure their operation. a example is
for FSMC_A17 (the _rs trigger, PD12)
#define PD_MODE_MASK 0xFC3FCF0F // all FMSC MODE bits
#define PD_MODE_FSMC 0xA22A8A2A // FMSC MODE values 10 alternate function
#define PD_OSPD_FSMC 0xf33fcf3f // FMSC OSPEED values 01 10MHz
but if you need to use FSMC_A16 pin (PD11) then it's
#define PD_MODE_MASK 0xF0FFCF0F // all FMSC MODE bits
#define PD_MODE_FSMC 0xA0AA8A0A // FMSC MODE values 10 alternate function
#define PD_OSPD_FSMC 0x50554505 // FMSC OSPEED values 01 10MHz
it's not often obvious what the value are ment to be in the manual (it's also not just in one manual but spread across a few ) how ever the cubeMX IDE can help you get the config right and then you take those values and paste into your example,
I do have a few examples on my github for using platformio and the above config for my MKS_TFT35_V1 lcd board
an example would be this which uses the stm32 cubemx (you can load the project into platformio or cubemx)
https://github.com/darkspr1te/mkstft35_V1_open_bootloader or his one which use bare metal more or less
https://github.com/darkspr1te/mkstft35_bl_altWell, I hope this helps, i'll post more after reading the links you have posted
regards
darkspr1te