Next step in porting: DISC0-STM32F746

Finally I’ve one of this in my hand…

#define STM32F746xx 1

#include <STM32F7.h>

#define DEVICE_TARGET STM32F7
#define DEVICE_NAME "DISCO-F746NG"
#define DEVICE_MANUFACTURER "STM32F746NG Discovery"
#define DEVICE_VERSION ((0ULL << 48) | (8ULL << 32) | (0ULL << 16) | (0ULL << 0))

#define USB_DEBUGGER_VENDOR_ID 0x1B9F
#define USB_DEBUGGER_PRODUCT_ID 0x5000

#define UART_DEBUGGER_INDEX 0
#define USB_DEBUGGER_INDEX 0

//#define DEBUGGER_SELECTOR_PIN PIN(B, 13)
//#define DEBUGGER_SELECTOR_PULL TinyCLR_Gpio_PinDriveMode::InputPullUp
//#define DEBUGGER_SELECTOR_USB_STATE TinyCLR_Gpio_PinValue::High
#define DEBUGGER_FORCE_API STM32F7_UsbClient_GetApi()
//#define DEBUGGER_FORCE_API STM32F7_Uart_GetApi()
#define DEBUGGER_FORCE_INDEX USB_DEBUGGER_INDEX

#define RUN_APP_FORCE_STATE true

#define DEPLOYMENT_SECTORS 	{{ 0x05, 0x08040000, 0x00040000 }, { 0x06, 0x08080000, 0x00040000 }, { 0x07, 0x080C0000, 0x00040000 } }

Porting started … but I’m only at the beginning …
Startup, Clock, boot and GPIO is done, now working on USB port setup…

7 Likes

Hey that’s great, I have one too, but haven’t been able to spend any time on yet as of yet. Keep sharing!!

John

Still working on USB… I’m facing NVIC Vectors problems for USB. Also USART and I2C drivers have to be partially rewritten. :pensive:

I’m happy to see the first tinyclr app deployed to stm32f746 via usart.
Still working on usb otg endpoints… :grimacing:

3 Likes

Very cool and keep at it :slight_smile: The more community porting TinyCLR the better it gets over time. We need others to dig into it and let us know what they find.

I’m facing more problems than I was thinking with the porting. The migration reference manual from ST is mostly funny than helpful.
I’ve ported to F7 Arduino STM32 package in 1h… with no problem.
I’ve implemented startup code (it works at 216Mhz), UART, PWM/timer, Interrupt, power (CAN/ADC/DAC implemented but not tested). I2C and SPI need more upgrades.
USB OTG FS doesn’t work at all and I’m getting crazy to figure out the problem (doesn’t reset and doesn’t fire interrupt at first glance, it seems completely dead).
Deploying the Tinyclr blink app via UART it works, but I get:

Create TS.

Loading Deployment Assemblies.

Resolving.

The debugging target runtime is loading the application assemblies and starting execution.
Ready.

Cannot find any entrypoint!

Sure that the CortexM7 LIB is correctly compiled and working?

try to see what one of the .netmf developers (CW2 from his code i learn a lot)was tried to port earlier for .netmf 4.4 and you can find here source for STM32F746NUCLEO and i belive you here you can find a lot things that can help you for porting of your discovery to TinyCLR (also .netmf 4.4 too)

Configuration

and DeviceCode target for STM32F7

i belive this source could help you a lot

2 Likes

Thank you @valon_hoti_gmail_com … I will take a look for sure. I’ve discovered now that deployment doesn’t work as expected on STM32F7.

Ok fixed deployment, now deploy and debug from VS is working fine. Blink app is running fine.

3 Likes

Fixed USB also, I had some defines not correctly set, but checking again (mostly 200 times) I got it e voilà USB working!
Thanks @valon_hoti_gmail_com for a hint in your startup code

Now I can deploy & debug via USB (FS)!

4 Likes

Domenico, my congrats. I hope your work becomes a treasure for other people who wants to enter the embedded world, including me. Keep us posted.

1 Like

I’m spending time these days to the board becouse I have some spare time unitl next week.
The board is running fine but few problems still exist, of course. The I2C bus need a major revision due to a bad joke from ST guys not preserving F4 compatibility. SPI is done but DISCO-746 has no free port. I’m looking into Display driver (mostly done, but not enough memory for the video cache, sigh!) so I’m studying to enable and use the on board QuadSPI 16MB as video layers cache.
These weekend I will deploy on github the F7 device code so it will be public.

2 Likes

:roll_eyes: Now working to port on 0.9.0 src code … but finally it works again also under 0.9.0.
I’m writing SDRAM enable code and mapping it in memory space. After that I (probably) can enable LDTC features on TinyCLR.

3 Likes

I have now enabled the SDRAM and mapped to LTDC VIDEO RAM in the code, the display correctly setup and clear.
I’m facing a problem with the Graphics managed library, becouse it gives me a OutOfMemoryException when try to allocate fromHdc. This is obvious if the Graphics call try to allocate 480x272x2=256K heap memory for the context.
Any suggestion ?
(PS: What is supposed to do the DisplayController.WriteString() method ?)

static void DisplayTest()
{
    DisplayController displayController = DisplayController.GetDefault();
    //var r = md.Init();                        
    displayController.ApplySettings(new ParallelDisplayControllerSettings
    {
        Width = 480,
        Height = 272,
        PixelClockRate = 9600000, // not used in native code
        PixelPolarity = false,
        OutputEnablePolarity = true,
        OutputEnableIsFixed = true,
        HorizontalFrontPorch = 32,
        HorizontalBackPorch = 13,
        HorizontalSyncPulseWidth = 41,
        HorizontalSyncPolarity = false,
        VerticalFrontPorch = 2,
        VerticalBackPorch = 2,
        VerticalSyncPulseWidth = 10,
        VerticalSyncPolarity = false,
        DataFormat = DisplayDataFormat.Rgb565 // not really correct: it is Rgb888 for Disco-746 display...
    });

    displayController.WriteString("Test");
    var screen = Graphics.FromHdc(displayController.Hdc);
    screen.Clear(Color.Black);
    var GreenPen = new Pen(Color.Blue);
    screen.DrawRectangle(GreenPen, 10, 10, 2, 10);
    screen.Flush();
}

Looking for a device on transport ‘USB’.
Found device port ‘USB’ with ID ‘dca38750-5539-4f4c-bb7d-8a50b9ba1088’ for transport ‘Usb’.
Starting device deployment.
Attempting to connect to device ‘USB:DISCO-F746NG’: iteration 0.
Opening port ‘\?\usb#vid_1b9f&pid_5000#6&1e013c1f&0&2#{c13bcfe9-5e84-4187-9baa-45597ffcbb6f}’.
Attaching debugger engine.
Debugger engine attached.
Querying device assemblies.
Found assemblies:

  • TinyCLR_M4 v1.0.0.0.
  • mscorlib v0.9.0.0.
  • GHIElectronics.TinyCLR.Devices v0.9.0.0.
  • GHIElectronics.TinyCLR.Drawing v0.9.0.0.
  • GHIElectronics.TinyCLR.Storage v0.9.0.0.
    Generating device specific assemblies.
    Deploying assemblies:
  • TinyCLR_M4 v1.0.0.0 with size 2.188 bytes at ‘H:\Embedded\PROJECTS\TinyCLR\TinyCLR_M4\TinyCLR_M4\bin\Debug\pe\TinyCLR_M4.pe’.
  • mscorlib v0.9.0.0 with size 77.204 bytes at ‘H:\Embedded\PROJECTS\TinyCLR\TinyCLR_M4\TinyCLR_M4\bin\Debug\pe\mscorlib.pe’.
  • GHIElectronics.TinyCLR.Devices v0.9.0.0 with size 50.324 bytes at ‘H:\Embedded\PROJECTS\TinyCLR\TinyCLR_M4\TinyCLR_M4\bin\Debug\pe\GHIElectronics.TinyCLR.Devices.pe’.
  • GHIElectronics.TinyCLR.Storage v0.9.0.0 with size 7.796 bytes at ‘H:\Embedded\PROJECTS\TinyCLR\TinyCLR_M4\TinyCLR_M4\bin\Debug\pe\GHIElectronics.TinyCLR.Storage.pe’.
    Total deployment size is 137.512 bytes.
    Incrementally deploying assemblies to the device:
  • Erasing sector 1 (262.144 bytes).
  • Writing sector 1 (2.192 bytes).
  • Erasing sector 3 (262.144 bytes).
  • Writing sector 3 (58.120 bytes).
    Assemblies deployed. There are 648.920 bytes left in the deployment area.
    Restarting interpreter.
    Attaching to device.
    Waiting for device to initialize.

Exception System.OutOfMemoryException - CLR_E_OUT_OF_MEMORY (1)

#### Message: 
#### System.Drawing.Internal.Bitmap::.ctor [IP: 0000] ####
#### System.Drawing.Graphics::.ctor [IP: 0006] ####
#### System.Drawing.Graphics::FromHdc [IP: 002d] ####
#### TinyCLR_M4.Program::DisplayTest [IP: 0086] ####
#### TinyCLR_M4.Program::Main [IP: 0004] ####

Eccezione generata: ‘System.OutOfMemoryException’ in GHIElectronics.TinyCLR.Drawing.dll
Eccezione non gestita di tipo ‘System.OutOfMemoryException’ in GHIElectronics.TinyCLR.Drawing.dll

Did you move heap from internal to external SDRAM?

Hi Dat, yes I moved heap to SDRAM, but I made SDRAM_Init() call to my SDRAM init code in wrong place. It need to be sitted in the SystemInit() otherwise It doesn’t work.

extern "C" {
    void __section("SectionForBootstrapOperations") SystemInit() {

	SCB_EnableICache();

        // enable FPU coprocessors (CP10, CP11)
        SCB->CPACR |= 0x3 << 2 * 10 | 0x3 << 2 * 11; // full access

#if DEBUG || _DEBUG
// configure jtag debug support
        DBGMCU->CR = DBGMCU_CR_DBG_SLEEP;
#endif

        // allow unaligned memory access and do not enforce 8 byte stack alignment
        SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk);

		// added by db
		PWR->CR1 = (PWR->CR1 & ~PWR_CR1_VOS_Msk)
			| PWR_CR1_VOS_1 | PWR_CR1_VOS_0;

        // for clock configuration the cpu has to run on the internal 16MHz oscillator
        RCC->CR |= RCC_CR_HSION;
        while (!(RCC->CR & RCC_CR_HSIRDY));

        RCC->CFGR = RCC_CFGR_SW_HSI;         // sysclk = AHB = APB1 = APB2 = HSI (16MHz)
        RCC->CR &= ~(RCC_CR_PLLON | RCC_CR_PLLI2SON); // pll off


#if RCC_PLLCFGR_PLLS_BITS == RCC_PLLCFGR_PLLSRC_HSE
// turn HSE on
        RCC->CR |= RCC_CR_HSEON;
        while (!(RCC->CR & RCC_CR_HSERDY));
#endif

            FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_BITS | FLASH_ACR_ARTEN;
        }

        // setup PLL
        RCC->PLLCFGR = RCC_PLLCFGR_PLL_BITS; // pll multipliers
        RCC->CR |= RCC_CR_PLLON;             // pll on
        while (!(RCC->CR & RCC_CR_PLLRDY));
		//while ((PWR->CSR1 & PWR_CSR1_VOSRDY) == 0);
        // final clock setup
		RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE_Msk | RCC_CFGR_PPRE1_Msk | RCC_CFGR_PPRE2_Msk));

        RCC->CFGR |= RCC_CFGR_SW_PLL          // sysclk = pll out (STM32F7_SYSTEM_CLOCK_HZ)
            | RCC_CFGR_HPRE_DIV_BITS   // AHB clock
            | RCC_CFGR_PPRE1_DIV_BITS  // APB1 clock
            | RCC_CFGR_PPRE2_DIV_BITS; // APB2 clock


		while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);

    // minimal peripheral clocks
#ifdef RCC_AHB1ENR_DTCMRAMEN
        RCC->AHB1ENR = RCC_AHB1ENR_DTCMRAMEN; // 64k RAM (DTCM)
#endif

	    RCC->AHB2ENR = 0;
	    RCC->AHB3ENR = 0;
        RCC->APB1ENR = RCC_APB1ENR_PWREN;    // PWR clock used for sleep;
        RCC->APB2ENR = RCC_APB2ENR_SYSCFGEN; // SYSCFG clock used for IO;

    // stop HSI clock
#if RCC_PLLCFGR_PLLS_BITS == RCC_PLLCFGR_PLLSRC_HSE
        RCC->CR &= ~RCC_CR_HSION;
#endif

        //SYSCFG->MEMRMP = 1; // map System memory to Boot area

#ifdef STM32F7_Enable_RTC
        STM32F7_RTC_Initialize(); // enable RTC
#endif

   // GPIO port A to D is always present
   RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;

#ifdef RCC_AHB1ENR_GPIOEEN
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
#endif

#ifdef RCC_AHB1ENR_GPIOFEN
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOFEN;
#endif

#ifdef RCC_AHB1ENR_GPIOGEN
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN;
#endif

#ifdef RCC_AHB1ENR_GPIOHEN
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOHEN;
#endif

#ifdef RCC_AHB1ENR_GPIOIEN
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOIEN;
#endif

#ifdef RCC_AHB1ENR_GPIOJEN
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOJEN;
#endif

#ifdef RCC_AHB1ENR_GPIOKEN
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOKEN;
#endif
	//STM32F7_DebugLed(true);
#ifdef USE_SDRAM_HEAP
	SDRAM_Init(); // Init MT48LC4M32 SDRAM for heap
#endif
    }

}

The LDF is updated to 1MB of Heap:

	ER_HEAP_BEGIN 0xC0000000 :
	{
		* (SectionForHeapBegin)
	}>SDRAM

	
	ER_HEAP_END 0xC00F0000 - 0x08 :
	{
		* (SectionForHeapEnd)
	}>SDRAM

Now it works fine and Graphics can allocate correcty the Hdc, but now I’m facing some problem with LDTC initialization…

LTDC driver is in F4 Ports. They are similar F7.

@Dat_Tran thank you for your suggestion. I’m aware that regs are mostly the same for F4 and F7.
The sdram seems to work fine and I tested it with big allocation of 2Mb arrays in managed code and native code with no problems at all. But when I apply settings in the DisplayController, mcu after one or two minutes or less goes lockup. This are typical memory issue, but I can’t find the couse…

I got a very tricky problem with framebuffer. It seems that SDRAM need a pullup and 100Mhz initialization on GPIO port for FMC due to some misterious reason, that is opposite to what ST shows (pullup none and 50Mhz with SDRAM CL=2 that is working for TinyCLR heap allocations). I suppose that when the mcu run at 216Mhz the ram is running at 108Mhz so 50Mhz delay on the GPIO pins is not enough for the LDTC direct memory reading …

After a some code rewrite of the Display driver now it basically works for the DISCO-746.

Now I found some problem sending data from managed code to native driver. For some reason when I set up:

    _display = DisplayController.GetDefault();
    ParallelDisplayControllerSettings _settings = new ParallelDisplayControllerSettings()
    {
        Width = 480,
        Height = 272,
        PixelClockRate = 9600000, // not used in native code
        PixelPolarity = false,
        OutputEnablePolarity = true, // this must be true
        OutputEnableIsFixed = true,
        HorizontalFrontPorch = 8,
        HorizontalBackPorch = 43,
        HorizontalSyncPulseWidth = 2,
        HorizontalSyncPolarity = false,
        VerticalFrontPorch = 2,
        VerticalBackPorch = 2,
        VerticalSyncPulseWidth = 10,
        VerticalSyncPolarity = false,
        DataFormat = DisplayDataFormat.Rgb565 // Must be RGB565
    };
                
    _display.ApplySettings(_settings);
    _display.WriteString("\f* Discovery STM32F746 board *\n\n");
    _display.WriteString  ("* TinyCLR 0.9.0 for STM32F7 *");

Apparently the config data are not correctly passed to native code. I got crazy to figure out what going wrong and I see that in the native code the if/else ALWAYS evaluate to true, setting wrong screen params.

//HorizontalSyncPolarity
if (m_STM32F7_DisplayHorizontalSyncPolarity == false)
    hltdc_F.Init.HSPolarity = LTDC_HSPOLARITY_AL; <--- I expect this
else
    hltdc_F.Init.HSPolarity = LTDC_HSPOLARITY_AH; <--- but it set this one
//VerticalSyncPolarity
if (m_STM32F7_DisplayVerticalSyncPolarity == false)
    hltdc_F.Init.VSPolarity = LTDC_VSPOLARITY_AL; <-- as previous
else
    hltdc_F.Init.VSPolarity = LTDC_VSPOLARITY_AH;
//OutputEnablePolarity
if (m_STM32F7_DisplayOutputEnablePolarity == false)
    hltdc_F.Init.DEPolarity = LTDC_DEPOLARITY_AL; <-- as previous
else
    hltdc_F.Init.DEPolarity = LTDC_DEPOLARITY_AH;
//OutputEnablePolarity
if (m_STM32F7_DisplayPixelPolarity == false)
    hltdc_F.Init.PCPolarity = LTDC_PCPOLARITY_IPC; <-- as previous
else
    hltdc_F.Init.PCPolarity = LTDC_GCR_PCPOL;    

Probably in STM32F7_Display_SetConfiguration() native call some params are screwed up.

2 Likes