Project - Cerberus firmware for NETMF 4.3RTM compiled with GCC + Quadrature encoder feature

As before - amazing! Thank you for the effort and sharing it.

Does this mean that we could use GCC to create firmware for the STM32F4DISCOVERY board using the stock 8Mhz crystal rather than having to do the HW mods?
Is it just a change in platform_selector.h ?

If we could compile the Oberon firmware with GCC…

I don’t have Windows 7 or 8 so I can’t test it (VS2012 doesn’t support Vista) - this might be the reason to change!

I think the CLR code will work with just a change in platform_selector.h. Maybe some issues with drivers. This should be tested.

You can. Start by a comparison between my code and Oberon code to find the differences.

Well I had to try… so having got my hands on a Windows 7 system to do some testing…

I followed Valkyrie-MT’s instructions earlier in this thread.
A single warning about " C:\MicroFrameworkPK_v4_3\Framework\Features\BlockStorage_PAL.libcatproj" cannot be imported again. It was already imported at “C:\MicroFrameworkPK_v4_3\Framework\Features\SD.featureproj” but no errors

Otherwise sucessfull. So I changed the external clock in platform_selector.h to 8Mhz and complied.
I flashed Tinybooter.hex using ST-Link - an advantage of the Discovery board.

Using MFDelpoy I now can find a USB device: Cerb-Family_Gadgeteer
Using ping the response is “TinyBooter” - looks good

However if I try to deploy ER_CONFIG I get an error:" No response from device"
same for ER_FLASH.

If I try connecting to Cerb-Family_Gadgeteer in MFDeploy it says “Connecting to Cerb-Family_Gadgeteer…Connected”

Some commands work:
Memory Map Command
Type Start Size

RAM 0x20000000 0x00020000
FLASH 0x08000000 0x00100000
Memory Map Complete

Flash Sector Map Command
Sector Start Size Usage

0    0x08000000  0x0000c000   Bootstrap
1    0x0800c000  0x00004000   Configuration
2    0x08010000  0x00010000   Code
3    0x08020000  0x00060000   Code
4    0x08080000  0x00080000   Deployment

Flash Sector Map Complete

I then tried using the Oberon 4.2 Tinybooter.hex.
Flashed with ST-Link
MFDeploy to load ER_CONFIG and ER_FLASH - no errors [The versions complied using GCC (8Mhz clock)]
Ping works. "TinyCLR"
Device capabilities includes : HalSystemInfo.halVersion:4.3.0.0 and ClrInfo.clrVendorInfo:Copyright GHI Electronics

Now for the good bit: using VS2012 and the basic default console application… it works!!

A newbie just following painting by numbers, but what progress! Thanks to NicolasG.

If someone can exmplain why Tinybooter (GCC 8 Mhz) isn’t working so much the better.

Next step to check whether SPI, I2C etc work.

COM ports work.

I am trying to use GHI.OSHW.Hardware but I can’t work out how to do it.
If I use the 4.2 assemblies it won’t work as the firmware is 4.3

Building the firmware doesn’t create the GHI.OSHW.Hardware assembly to use in the VS IDE.
I tried to build the the project at C:\MicroFrameworkPK_v4_3\DeviceCode\GHI\Libraries\GHI.OSHW.Hardware\GHI.OSHW.Hardware.sln setting the NETMF to 4.3
It builds but when I use it in a project I get:
ERROR!!! Firmware version does not match managed code version!!!
Invalid native checksum: GHI.OSHW.Hardware 0x00000000!=0xF0D4135D

I am confused as the firmware is built against the code in C:\MicroFrameworkPK_v4_3\DeviceCode\GHI\Libraries\GHI.OSHW.Hardware
How do you compile or get version of the GHI.OSHW.Hardware assembly to use in the IDE?

I have been getting the same error for the last 3 days. If you retarget the GHI.OSHW.Hardware project from 4.2 to 4.3, it no longer compiles unless you uncheck generate stubs. Something about an invalid “.” character… But when I use this recompiled DLL, it still fails with the checksum error. It looks like this GHI.OSHW.Hardware is a Managed API to some native methods. This is similar to what was done by CW2 in his OneWire implementation. I was considering reworking it, using that as a model.

I found that VS2012 Release compilation doesn’t work for interop managed code. The checksum is always NULL.
Try compile it in debug mode and the cheksum should be OK.

I couldn’t get it to work.
If I use GHI.OSHW.Hardware project compiled for debug, with the release firmware I still get the checksum error.
If I recompile the firmware for debug it fails with 11 Warning(s) and 2 Error(s). The first problem seems to appear as:

Any suggestions?

NicolasG should we move this, and the following issue to your generic topic [quote]Cerberus Firmware for NetMF 4.3 compiled with GCC[/quote] as these issues are not related to you Quadrature encoder feature?

Separate issue: I tried swapping COM1 and COM2 to experiment with changing the port/pins allocation.
I edited platform_selector.h

//#define STM32F4_UART_RXD_PINS {39, 3, 27} // C7, A3, B11 original GCC version
//#define STM32F4_UART_TXD_PINS {38, 2, 26} // C6, A2, B10 original GCC version
 #define STM32F4_UART_RXD_PINS { 3,39, 27} // A3, C7, B11 SAB attempt
 #define STM32F4_UART_TXD_PINS { 2,38, 26} // A2, C6, B10 SAB attempt
//#define STM32F4_UART_CTS_PINS {109, 0, 29} // G13, A0, B13 original GCC version
//#define STM32F4_UART_RTS_PINS {108, 1, 30} // G12, A1, B14 original GCC version
 #define STM32F4_UART_CTS_PINS { 0,109, 29} //  A0,G13, B13 SAB attempt
 #define STM32F4_UART_RTS_PINS { 1,108, 30} //  A1,G12, B14 SAB attempt

Compiles and loads fine.
Responds to HardwareProvider methods to list pins, baud rates etc.
But fails and hangs on using serial functions such as [quote]UART.Read(rx_byte, 0, 1);[/quote]
Are pins/ports configured elsewhere in the firmware not just defined/configured in platform_selector?

NicolasG
How did you create the version of your Cerberus_Hardware assembly that you put in the “Ready to use” directory?
That works without an error.

If I build it using VS2012 I get the checksum error the same as the GHI.OSHW.Hardware assembly

There is a bug in the stub creation process with project name containing ‘.’ (dot).
The featureproj file creation is new in 4.1 and is not use by GHI, you can try to remove it from “C:\Program Files (x86)\MSBuild\Microsoft.NET Micro Framework\v4.3\Device.targets” and then update the native code checksum with the generated one in stubs.
Compare this file with the v4.1 version.
Sorry, I can’t test it now.
Incidentally, this is why my namespace is Cerberus_Hardware and not Cerberus.Hardware…

I think the solution to that issue will be a good candidate for a Wiki entry.

@ patc:

Did you ever take a look at following articles?

I know its not a good solution for the checksum problem, as there is no real check that the firmware and the assembly are in check - but it works for testing: change the checksum in the native code to 0x00000000 and recomplie the firmware. I now have a working version of GHI.OSHW.Hardware assembly under NETMF 4.3 using GCC!

NicolasG must have found a way to create correct asssembly.pe files with checksums. - but per his last post is busy. (and he has done so much already)

Now if someone can explain either how to create the assembly.pe file with the correct checksum, or how to change the checksum in a .pe file then we will have a better solution.

I post a new codeshare entry for GHI.OSHW for NETMF 4.3 and the fix to build such interop project.
http://www.tinyclr.com/codeshare/entry/627

@ ianlee74 - Hi Ianlee, I don’t see a response to your question about the FPU. Did you ever get (of figure out) the answer to that question?

Tx :slight_smile:

@ JackN - When I did the initial back port of the changes required to build with GCC to 4.2 I ran some performance tests. The results of which would indicate that the stock firmware, at the time at least, did not leverage the FPU.

http://www.tinyclr.com/forum/topic?id=10297

I have not repeated the tests with the latest GHI released firmware, so I do not know if this is still the case.

I think you meant to say “did [not] leverage”

Thanks Ian, you are correct. I will update the post to avoid any confusion.

Could anyone made the ethernet go to work with NETMF 4.3RTM?

For me I can compile and run my own firmware with ethernet and SD-card support for NETMF 4.2 successfully.
I also can compile and run the firmware with SD-card support for NETMF 4.3.
But the compiled firmware with ethernet for NETMF 4.3, doesn’t work. I get an exception when calling ‘EnableDhcp()’ on the instance of NetworkInterface.
EnableStaticIP() doesn’t work as well.

Had anyone more success on it, than me?

btw: really great job NicolasG

As a relative noob, could you tell me what it would take to use this? I’m very interested in using the quadrature encoder functionality for two encoders. In non-NETMF, the quadrature encoder functionality seems pretty prominent in usage.

I’m upgraded my Cerbuino firmware a few times using STDFUTester and MFDeploy using the standard updated firmwares published by GHI.

I’m assuming that I could use the STDFUTester to download TinyBooter_4_3_0_0.dfu, and then use MFDeploy to download ER_CONFIG AND ER_FLASH. But then I would bet I would have to update to NETMF 4.3 and I may run into issues with version mismatches.

Am I being overly concerned, or am I missing any key concepts in doing this?

You can only use the same order of U(S)ART ports, not reorder them by only changing platform_selector.h. There, you can only change the pins used for a given U(S)ART, i. e., you can change COM2 (which will always use USART2) from using PA3,PA2 to using PA8,PA9 or PA10,PA11.

The direct mapping of the COM number to the U(S)ART number is hard coded in CPU_USART_Initialize(), see DeviceCode\Targets\Native\STM32F4\DeviceCode\STM32F4_USART\STM32F4_usart_functions.cpp

There is another issue, though: CPU_USART_Initialize() from the comunity edition is broken IMO, because it caters for a specific mapping that appears to be specific to Cerbuino boards. It contains comments like “USART1 is really USART6” which I had a hard time understanding at first - it should really read “On Cerbuino, COM1 is mapped to USART6”. I still think that this mapping is misplaced in a file that should be valid for all STM32F4 boards and allow one to use all six U(S)ARTs, though, so I replaced these lines by the original ones from Oberon’s 4.2 implementation:


BOOL CPU_USART_Initialize( int ComPortNum, int BaudRate, int Parity, int DataBits, int StopBits, int FlowValue )
{
    if (ComPortNum >= TOTAL_USART_PORT) return FALSE;
    if (Parity >= USART_PARITY_MARK) return FALSE;
    
    GLOBAL_LOCK(irq);
    
    ptr_USART_TypeDef uart = g_STM32F4_Uart_Ports[ComPortNum];
    UINT32 clk;
    
    // enable UART clock
    if (ComPortNum == 5) { // COM6 on APB2
        RCC->APB2ENR |= RCC_APB2ENR_USART6EN;
        clk = SYSTEM_APB2_CLOCK_HZ;
    } else if (ComPortNum) { // COM2-5 on APB1
        RCC->APB1ENR |= RCC_APB1ENR_USART2EN >> 1 << ComPortNum;
        clk = SYSTEM_APB1_CLOCK_HZ;
    } else { // COM1 on APB2
        RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
        clk = SYSTEM_APB2_CLOCK_HZ;
    }
    
    //  baudrate
    UINT16 div = (UINT16)((clk + (BaudRate >> 1)) / BaudRate); // rounded
    uart->BRR = div;
    
    // control
    UINT16 ctrl = USART_CR1_TE | USART_CR1_RE;
    if (DataBits == 9) ctrl |= USART_CR1_M;
    if (Parity) ctrl |= USART_CR1_PCE;
    if (Parity == USART_PARITY_ODD) ctrl |= USART_CR1_PS;
    uart->CR1 = ctrl;
    
    if (StopBits == USART_STOP_BITS_ONE)
		StopBits = 0;
    uart->CR2 = (UINT16)(StopBits << 12);
    
    ctrl = 0;
    if (FlowValue & USART_FLOW_HW_OUT_EN) ctrl |= USART_CR3_CTSE;
    if (FlowValue & USART_FLOW_HW_IN_EN)  ctrl |= USART_CR3_RTSE;
    uart->CR3 = ctrl;

    GPIO_PIN rxPin, txPin, ctsPin, rtsPin;
    CPU_USART_GetPins(ComPortNum, rxPin, txPin, ctsPin, rtsPin);
    UINT32 alternate = 0x72; // AF7 = USART1-3
    if (ComPortNum >= 3) alternate = 0x82; // AF8 = UART4-6
    CPU_GPIO_DisablePin(rxPin, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate);
    CPU_GPIO_DisablePin(txPin, RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate);
    if (FlowValue & USART_FLOW_HW_OUT_EN) {
        if (ctsPin == GPIO_PIN_NONE) return FALSE;
        CPU_GPIO_DisablePin(ctsPin, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)alternate);
    }
    if (FlowValue & USART_FLOW_HW_IN_EN) {
        if (rtsPin == GPIO_PIN_NONE) return FALSE;
        CPU_GPIO_DisablePin(rtsPin, RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate);
    }
    
    CPU_USART_ProtectPins(ComPortNum, FALSE);
    
    switch (ComPortNum) {
    case 0: CPU_INTC_ActivateInterrupt(USART1_IRQn, STM32F4_USART_Interrupt0, 0); break;
    case 1: CPU_INTC_ActivateInterrupt(USART2_IRQn, STM32F4_USART_Interrupt1, 0); break;
    case 2: CPU_INTC_ActivateInterrupt(USART3_IRQn, STM32F4_USART_Interrupt2, 0); break;
    case 3: CPU_INTC_ActivateInterrupt(UART4_IRQn, STM32F4_USART_Interrupt3, 0); break;
    case 4: CPU_INTC_ActivateInterrupt(UART5_IRQn, STM32F4_USART_Interrupt4, 0); break;
    case 5: CPU_INTC_ActivateInterrupt(USART6_IRQn, STM32F4_USART_Interrupt5, 0);
    }

    uart->CR1 |= USART_CR1_UE; // start uart

    return TRUE;
}

After deploying the config.hex and firmware.hex file (from the ready to use folder) to my cerb40 with MFDeploy, the usb driver does not recognize my cerb40 anymore.

in device manager i can see an uninstalled device called “cerb-family”.
i tried to install the drivers for this device manually by searching for drivers in
"C:\Program Files (x86)\GHI Electronics\GHI Premium NETMF v4.2 SDK\USB Drivers", without success.

can anyone help me?