Creating a Native Driver for FEZ Cerberus. Need native reference help

Hi all,

I have a FEZ Cerberus that I have been tinkering with for a while. I have a project that I wanted to implement CAN BUS communications on. My background is all C#. I have just started to dibble into c/c++. The whole reason I’ve decided to do a native driver, is because the managed CAN driver in the showcase, is way to slow for my application. I need to receive data at around 500kbs at 40% bus load.

I have written an example CAN driver using the DSP_Lib from STMicroelectronics. Deployed it to the FEZ Cerberus and it works great, but its all in native code :confused:

I have searched and searched this forum, and the internet. However I havent had much luck in examples. I do know that GHI offers premium hardware, but I really wanna stay OSHW for future changes and nerding :slight_smile:

I have successfully downloaded the 4.3 community port, and have built the FEZ Cerberus firmware and deployed back to the device. I also have wrote a small test interop that can be successfully called from Managed code.

So here is the problems i’m hitting.

  1. How can I accomplish Connecting the CAN pins to AF9? For example, I would use GPIO_PinAFConfig(params here) to accomplish this using the StdPeriphDriver. I have searched around the PK to see if I could find any custom driver examples, but have not had any luck :confused: However, I thought i found a small lead I thought in the STM32F4_i2c_function, but I cant get the reference to work in my native driver :confused:
  2. How to configure the pins. Again, I cannot find any references living already in the PK for something like GPIO_InitStructure.
  3. Can I reuse existing code from the DSP library? If so, how do I reference it in the native code for the PK?

I have tried several steps to get everything working. However, every time I add a reference or try to add code referencing the Stm32 framework, It fails to compile.

Here is some details about my setup
Windows 8.1 x64
GCC 4.6.2
GHI 4.3 community port
Fez Cerebus

Here is some native code I’m trying to gain access to somehow.
What I think should already be in the PK for STM32F4

GPIO_PinAFConfig()
RCC_AHB1PeriphClockCmd()
RCC_APB1PeriphClockCmd()
GPIO_InitStructure
NVIC_InitTypeDef
NVIC_Init

Things I want to add from the DSP Lib

CAN_Init()
CAN_Receive()
CAN_ITConfig()
CAN_FilterInit()
CAN_FilterInitStructure
CAN_InitStructure

I hope all this makes sense, i seriously suck at explaining things :slight_smile:

Any hints, or examples is greatly appreciated!

-Matt

Those “native functions” you’re talking about are from the CMSIS library. While CMSIS is the recommended way of doing C development on Cortex microcontrollers, I haven’t seen it used by any NETMF ports. This is probably because CMSIS is really designed for static, not dynamic, calls – for example, to initialize a GPIO pin, you create a GPIO_Init struct (initialized statically), and you pass a reference to that into the GPIO_Init() function. CMSIS is written in a way such that MDK can compile-time optimize those calls into efficient GPIO register writes.

To implement the NETMF GPIO functions (again, as an example – but it extends to all CMSIS functions), you’d end up with either tons of switch-case statements, or very ugly-looking stuff. Stuff like:


// Implementing NETMF's HAL_GPIO_EnableInputPin() function using CMSIS.
BOOL HAL_GPIO_EnableInputPin( GPIO_PIN Pin, BOOL GlitchFilterEnable, GPIO_INTERRUPT_SERVICE_ROUTINE PIN_ISR, GPIO_INT_EDGE IntEdge, GPIO_RESISTOR ResistorState )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = (Pin & 0x0F);
    GPIO_InitStructure.GPIO_Mode = ResistorState? GPIO_Mode_IPU : 0x00;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(&GPIOA+((u32 *)((Pin & 0xF0) >> 8)), &GPIO_InitStructure); // get the GPIO port from the NETMF Pin.

    ...
}

So, while CMSIS works really well for bare-metal projects, it’s a shim that NETMF ports typically don’t use. If you look through the STM32F4 processor code in the PK, you’ll notice all functions are implemented as direct register writes.

So, you’re not going to be able to call any of those functions without including the library. Since the library functions are just wrappers for register writes, there’s no reason you can’t mix your new custom code (using CMSIS library calls) with the existing PK code (using raw register writes).