Llilum is blinking to me

And for the first time I even got a blink from llilum on an LPC1768. Without the help of @ MCalsyn, this would have not been possible, thanks for that.

Now the rest of tests can begin … and than the next board and …

8 Likes

Congrats!

What does the .NET code for this look like?

@ ianlee74 - if one does start a new project and selects Llilum application this is what you get, no changes made … yet

That is the easy part, getting there is the hard part. Building the LLVM compiler, the LlilumSDK and VSIXes (yes, 2) and all in the correct way in setting up the toolchain and whatever comes along is … very challenging to me.

//
// Copyright (c) Microsoft Corporation.    All rights reserved.
//

 #define LPC1768
//#define K64F
//#define STM32F411
//#define STM32F401
//#define STM32F091

namespace Managed
{
    using System;
    using Windows.Devices.Gpio;
    using System.Runtime.InteropServices;
    using System.Threading;

 #if LPC1768
    using Microsoft.Llilum.LPC1768;
 #elif K64F
    using Microsoft.Llilum.K64F;
 #elif STM32F411
    using Microsoft.Llilum.STM32F411;
 #elif STM32F401
    using Microsoft.Llilum.STM32F401;
 #elif STM32F091
    using Microsoft.Llilum.STM32F091;
 #endif

    class Program
    {
        // Example of C interop functions
        [DllImport("C")]
        private static extern int AddOneInterop(int input);


        const float period = 0.75f;
        const float timePerMode = 4.0f;

        static int[] pinNumbers =
        {
 #if (LPC1768)
            (int)PinName.LED1,
            (int)PinName.LED4,
 #elif (K64F)
            (int)PinName.LED_BLUE,
            (int)PinName.LED_RED,
 #elif (STM32F411 || STM32F401 || STM32F091)
            (int)PinName.LED1,
            (int)PinName.LED1,
 #else
 #error No target board defined.
 #endif
        };

        static void Main()
        {
            var controller = GpioController.GetDefault();

            var threadToggledPin = controller.OpenPin(pinNumbers[0]);

 #if (STM32F411 || STM32F401 || STM32F091)
            var loopToggledPin = threadToggledPin;
 #else
            var loopToggledPin = controller.OpenPin(pinNumbers[1]);
 #endif
            threadToggledPin.SetDriveMode(GpioPinDriveMode.Output);
            loopToggledPin.SetDriveMode(GpioPinDriveMode.Output);

            int threadPinState = 1;
            int loopPinState = 1;

            // Toggling a pin with a thread
            var ev = new AutoResetEvent(false);
            var solitaryBlinker = new Thread(delegate ()
            {
                while (true)
                {
                    ev.WaitOne(1000, false);

                    threadToggledPin.Write((GpioPinValue)threadPinState);

                    // Using the C interop here
                    threadPinState = AddOneInterop(threadPinState) % 2;
                }
            });
            solitaryBlinker.Start();

            // Toggling a pin in a loop
            long last = DateTime.Now.Ticks;

            while (true)
            {
                long now = DateTime.Now.Ticks;

                // Toggle every 500ms
                if (now > (last + 5000000))
                {
                    last = now;

                    // Toggle the pin
                    loopToggledPin.Write((GpioPinValue)loopPinState);

                    // Using the C interop here
                    loopPinState = AddOneInterop(loopPinState) % 2;
                }
            }
        }
    }
}

3 Likes

Can you tell us what the maximum blink rate is with Llilum? I don’t actually care if the LED actually blinks, I’m more interested in how fast you can toggle a pin as I was kind of disappointed with the test results I got when I first started down the .Net Micro road.

Thanks

@ Gene - you can read all the details about a LED blink perf tests here:

1 Like

@ JSimoes -

And they aren’t done squeezing this yet, but that is pretty good.

@ Duke Nukem - can’t wait for that to be available!! :wink:

Hm, using this piece of - master work - only brings me 200 KHz … up for the next try …

namespace Managed
{
    using Windows.Devices.Gpio;
    using Microsoft.Llilum.LPC1768;

    class Program
    {
        static void Main()
        {
            var ctlr = GpioController.GetDefault();

            var gpioPin = ctlr.OpenPin((int)PinName.p8);

            gpioPin.SetDriveMode(GpioPinDriveMode.Output);

            while (true)
            {
                gpioPin.Write(GpioPinValue.High);
                gpioPin.Write(GpioPinValue.Low);
            }
        }
    }
}

@ JSimoes - Is the Zelig they refer to a synonym for Llilum?

1 Like

No, Zelig is part of Llilum. Best as I can tell, Llilum consists of

[ul]Zelig (compiletime, debugtime support)
The LlilumSDK (basically an install wrapper for the llvm toolchain components)
A Visual Studio dir containing a couple vsix extensions for Visual Studio to add new project templates and build/deploy integration
an mbed-based hardware abstraction
LLVM compiler (external component)
GCC ARM toolchain (external component)[/ul]

1 Like

Finally got a Nucleo 411RE and LPC1768 and got Llilum working on both. Porting to the 411CE should be straightforward enough (famous last words), but all the 411CE boards I have (Oxygen, Oracs, and Verdant Smart Node) lack JTAG/SWD pins, so it’s anyone’s guess what’s up when things go wrong. I’m no STM32 wizard, and I am probably messing up the clock setup because USB ceases to work outside DFU mode.

That said, I’m having a great time with the 411RE and have started porting some stuff to Llilum, including taking a stab at porting some of my driver code for intelligent interfaces (ESP and friends). Azure, here we come!

This is a total side project (to all my other side projects) and I have only put in a half day so far getting the basic stuff running, and another half day of playing with code porting, but it is fun, and blazing fast at runtime. Builds are a bit pokey due to all the llvm work that has to happen, but it is at least two orders of magnitude faster at runtime. I suspect things would run faster if I had built the SDK as ‘release’. It is still not ready for prime time as there are still rough edges in the language support, but it’s impressive how good it is already.

3 Likes

@ mcalsyn - I am almost sure you know CubeMX a nice ST tool to generate code to set the clock [url]STM32CubeMX - STM32Cube initialization code generator - STMicroelectronics

3 Likes

@ RobvanSchelven - Excellent! Thanks! - no, that was news to me. These are totally new waters for me.

I have done netmf firmware changes before to add functionality, but have never fiddled around ‘close to the metal’ with the STM32 family.

Thanks again for the tip!

1 Like

@ mcalsyn - Now this is cool …

BTW: - Got my SDK compiled and with the F091, L152 dlls as well but don’t compile with a demo Blinky app … :wall:

With the LPC if I use managed I2C, the middle LEDs come to live all of a sudden, if that should be ???

With the I2C on a 411RE, it don’t work, yet … but your progress is making me to re-test :dance:

[EDIT] For the performance on a 411RE, I got a 20+ times performance increase in managed code for swapping a pin(g), one pin(g) only!

I wonder if it is maybe using the wrong hardware model. You have to change hardware in two places - the compile constants in program.cs (if you are starting from the template code) and in the Native project properties.

See ‘Device Setup’ here : [url]https://github.com/NETMF/llilum/wiki/SDK-User-Guide[/url] They don’t talk about the program.cs, change, but it is necessary.

Also, be sure to always ‘rebuild solution’.

I am still using the same SDK and vsix bits that I posted to DropBox.

If anyone else wants to try those bits, you can find them here : Dropbox - File Deleted - Simplify your life
You will still need to install the GCC and mbed driver pre-requisites. This is just a copy of my build by-products, so no guarantees that it will do anything more interesting than take up space on your disk (though .Peter. had some luck with them).

EDIT: Still haven’t gotten debugging to work, but I am convinced that I haven’t installed the right pieces yet. I think I need OpenOCD instead of PyOCD.

@ mcalsyn - I’ve already change the native project setting for llilum board to 411re and change to OCD (and even installed) and use st-link to deploy. I only do rebuild and then deploy and the blinky does go, even on an external port (D2) so I’m pretty sure the board config etc. are correct otherwise the 411re wouldn’t even start.

I’ll try again later on when I get to my nukes.

I could be mistaken but you should be able to use an existing nucleo board (with JTAG/SWD) to debug another, but if that counts for oxygen I can’t tell. Never used JTAG/SWD, well at least not knowingly … :think:

How did you set up ST-Link to deploy from VS? I have been using drag and drop to the Nucleo 411RE. F5 to deploy just hangs for me.

You are right about using the Nucleo ST sub-module for JTAG, but the problem is that none of my 411CE boards have all the right pins brought out. Oxygen is missing the SWO pin and the others are missing one or both of TCLK or TMS, so none of them have the full set of JTAG/SWD pins brought out.

EDIT: nevermind - figured it out - achievements unlocked: deploy and debug

1 Like

@ mcalsyn - Can you set a break point and hit it to continue with stepper working (F10/F11) ??

@ .Peter. - Yes, but not with the binaries on dropbox. I will need to post new binaries that have OpenOCD in them.

There is a workaround though if you want to play before I do that.

  1. Install openocd by copying the files as instructed here (copy to two places - check the readme files in each dir) : [url]https://github.com/NETMF/llilum/wiki/Open-OCD-and-STM32-Board-Usage[/url]
  2. undocumented step: Get the sysinternals pskill.exe program and put it in your path as kill.exe
  3. Set your debugger (in Native project → Properties → Debugging) to OpenOCD
  4. Press F5
  5. After deployment, but before the the attempt to connect to the debugger times out, run llilum\Zelig\LLVM2IR_results\mbed\simple\debugSTM32F411.bat but don’t move on past the pause in the bat file - that is don’t hit space or enter when prompted. You just want the script to start OpenOCD but NOT to start GDB.
  6. Your debug session should start. You may need to hit the PAUSE button in VS to break into the program. If you are too slow and get an error about port 3333, then try again and type faster :slight_smile: You want to catch it after build and deploy, but before it gets tired of waiting for the debugger. You have to do this every time because VS will kill OpenOCD every time you rebuild or press F5.

Again, these are just workaround until I rebuild the SDK vsix with OpenOCD

2 Likes

@ mcalsyn - Thanks, it works !!

1 Like