NETMF / netmf-interpreter

.NET Micro Framework Interpreter
http://netmf.github.io/netmf-interpreter/
Other
486 stars 223 forks source link

STM32F7 support #482

Open Untitled86 opened 7 years ago

Untitled86 commented 7 years ago

I've been using NETMF with STM32F4 chips for some time now. Recently my employer started designing boards with STM32F7 chips. Naturally I need to be able to support them, or ditch NETMF.

Can someone point me at the best/simplest path to "port" NETMF to this new chip?

I'm not an expert when it comes to MPUs. I've done a lot of NETMF coding in C# and a fair amount of C/CPP customizations to our firmware/runtime (mostly tweaking hardware feature drivers and moving slow bits from C# to CPP).

Of course, I will post whatever I end up with if I'm able to get this working.

Thanks!

This probably goes without adding... But NETMF is slipping into the abyss. While embedded everything is exploding NETMF isn't. Adding support for the latest STM chip (when it probably isn't a ton of work) seems like a good idea. Unless it is a ton of work, in which case, please tell me so I can dump NETMF.

LodinErikson commented 7 years ago

Same here. We discussing to use the STM32F7-Disco as a base for the next development. I read somewhere that the code for F4 should be the same for F7, but I don't know it. I have many years of experience developing SMALL embedded systems, but a NETMF port is realy beyond my abilities.

doingnz commented 7 years ago

A port to STM 32F746GDISCOVERY specifically would be ideal as it is inexpensive (US $49), and includes LCD 480x272 with touch and various IO.

http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-discovery-kits/32f746gdiscovery.html

piwi1263 commented 7 years ago

Hi Guys, I just tried to use a 411 based image and tried it on a 746ZG doesn't fly, neither is it for the 412ZG. the latter one is even closer to the 411. Both giving me the USB Descriptor not found error. The code might be compatible but you need to rerun the compile of netmf with the appropriate dev specs. And there might be an adjustment here or there. Something alike https://github.com/NETMF/netmf-interpreter/blob/dev/Solutions/STM32F4DISCOVERY/platform_selector.h

cw2 commented 7 years ago

I have not yet had a chance to dig deeper into particular differences between STM32F4 and F7, but in general, you'd most likely need to adjust interrupt controller configuration (usually, the number of IRQ handlers is different), memory layout (assuming F7 is superset of F4) and clock settings (in platform_selector.h mentioned above).

I have been already looking at F7 discovery board, but most likely will not get it before autumn. Unless, of course, someone convinces me otherwise :)

josesimoes commented 7 years ago

Because it leverages ST's official HAL for any STM32 series, PR #434 can give you a good start on that, but it still requires some work before being completely usable...

cw2 commented 7 years ago

Well, software is usually not a problem - embedded development boards have rather low WAF, especially during the holiday season :cry:

Untitled86 commented 7 years ago

Thanks for all the posts. By the way, this amazing guy already did the port for Llilum. Doesn't that make this port to NETMF simpler?

https://github.com/roceh/stm32f7disco_llilum_lcdtest/issues/1

smaillet-ms commented 7 years ago

Ideally it would, however Llilum and NETMF use very different platform Abstraction layers at this point. One of the things I'm working on (and really need to commit to a complete written description) is to define a unified PAL that would allow both to share the same PAL allowing for better compare/contrast and migration as appropriate.

That said, having working code as a reference for the startup and clocks, IRQs and Pin maps certainly makes things easier.

Untitled86 commented 7 years ago

Today I'm attempting to add support to NETMF for F7. I found the peripheral libraries online. Starting with the F4 code I moved all the code and header files in place, renamed all the folders, updated all the project files, etc. Next I updated the clock info in the Platform_selector.h from that other project. Now I'm running into differences that are more substantial. The bootstrap code for the F4 references a constant that doesn't exist in the F7 version of ST's H files. ...Anyways

I'm going to see how far I can get on my own. I'll upload my progress here and maybe someone can help me. I have about a week to do this. If I cannot make this happen I will likely be forced by my employer to switch to FreeRTOS.

This would be tragic. I've done some pretty awesome things with NETMF. One of our instruments (a UV-VIS-NIR spectrometer) uses complex math to detect how much of something is in the item being measured (chemometric models). For example if you scan a mango it can tell you how much sugar is in it. We implemented NIPLS (Non-iterative partial least squares) which works well but, because I used NETMF, I was able to allow users to write their own "plugins" using our desktop app (also C#) to implement their own math. There are lots of various "maths" that work better for different purposes. LDA for example is better at identifying things, but not as good at identifying the quantity of a given thing. ...E.g. does the mango have any sugar vs how much sugar does it have. I also gave users the ability to customize the screen and write macros (like Outlook rules) to change content dynamically. ...Things I can't do with FreeRTOS. This code is live, in production, being used successfully. I am going to be very unhappy if I have to re-write this in C/CPP just because NETMF wasn't kept current. ...I'm probably not the only one in this kind of situation.

If you're curious, this is that products page on our site (https://www.felixinstruments.com/food-science-instruments/portable-nir-analyzers/f-750-produce-quality-meter/). Unfortunately our marketing people don't highlight the features I talked about. Really they're more the type of feature that's important to have when you need it, but not really that sexy during a sale. ...The instrument is so large because the spectrometer is a very expensive Zeiss MMS1 spectrometer. That screen, it's a daylight visible memory LCD from Sharp (like E-Ink but better). I have a nice light-weight SPI driver for that, which includes very fast drawing for fonts, etc. The font characters are stored by their Unicode and the device even supports switching to Chinese/Hewbrew characters on the fly. There's a small desktop app that converts the TrueType fonts to compressed black and white bitmaps in three font sizes. And, most importantly, it renders them very quickly on the device. ...The device performs great at 168Mhz with ~120K of internal memory, and 4MB of slow external memory. The move to the F7 isn't for speed, we were motivated by the added support for cheaper faster external memory.

I've been too busy to share a lot of my code, but my employer was onboard with that the last time I spoke with him. Anyways, rant complete. The point is that I've invested too much in NETMF to give it up.

piwi1263 commented 7 years ago

@Untitled86 There is light at the end of the tunnel, so do not abandon netmf on F7 to soon ...

josesimoes commented 7 years ago

@Untitled86 An awesome example of what can be done with NETMF!! Great work there. 👏

LodinErikson commented 7 years ago

@Untitled86 Any news on this ? Maybe I can give you (very) little help. I have no idea how to use the SDK, github or the needed folder structure, but I have a licensed MDK pro with some experience with it. And yes, I know my English is terrible, but I try my best... or google translate :)

Untitled86 commented 7 years ago

Yes! I've got my board beeping and flashing LEDs! No USB or other peripherals. ...And I'm using the 4.3 codebase at the moment, just because I'm familiar with it. I plan on using 4.4 once I sort out everything.

Some key important changes are the clock (of course) and memory address changes. The F7 supports two flash modes, ITCM or AXIM. Those change the address you use to access flash memory. It's 0x08000000 for AXIM and 0x00200000 for ITCM. The boot option bytes control the mode used, along with how the board is wired. Ours was wired for ITCM. HOWEVER, in DFU mode (which is how I program boards) it ALWAYS boots to AXIM mode. So confusingly you setup your firmware for 0x002... but when you use STDFU Tester you flash to 0x080...

Also the SRAM + CCM addresses changed... 0x20000000 (64K CCM aka TCM) 0x20010000 (320K SRAM) 0x2004C000 (16K SRAM)

I'm using these settings for my clock in platform_selector...

define SYSTEM_CLOCK_HZ 216000000

define SYSTEM_CYCLE_CLOCK_HZ 216000000

define SYSTEM_APB1_CLOCK_HZ 54000000

define SYSTEM_APB2_CLOCK_HZ 108000000

define SYSTEM_CRYSTAL_CLOCK_HZ 12000000 //Disco is 25MHz, we use 12Mhz

Now I just have to get all the peripherals working! :) No problem right? I'll post my code to my GitHub.

Untitled86 commented 7 years ago

Ok, I've run into another wall. I must be setting the clocks up wrong. I used the F4's Bootstrap file as a starting place. There the RCC_PLLCFGR_PLLN_BITS, RCC_PLLCFGR_PLLP_BITS, RCC_PLLCFGR_PLLQ_BITS, etc. are probably all being set wrong.

I can execute this code no problem... CPU_GPIO_EnableOutputPin((GPIO_PIN)((1 * 16) + 12), true ); CPU_GPIO_EnableOutputPin((GPIO_PIN)((1 * 16) + 12), false );

And my beeper beeps. Well, it clicks. with no delay it's barely audible. If I don't put the pin low it beeps very loudly. So that's working. But if I execute this code... CPU_GPIO_EnableOutputPin((GPIO_PIN)((1 * 16) + 12), true ); HAL_Time_Sleep_MicroSeconds(1000); CPU_GPIO_EnableOutputPin((GPIO_PIN)((1 * 16) + 12), false );

It hangs forever. So... If anyone wants to help, I've uploaded my bootstrap file to Onedrive... https://1drv.ms/u/s!AsDrOapsdMSUk7ZsEG11OtNuqQzclQ

Also, any general advise if I'm headed in the wrong direction would be great.

Thanks in advance! I'll be looking for examples of how other people setup the clock. As mentioned above, I'm using a 12Mhz external clock instead of the 25Mhz used on the Disco. And my target processor speed is 216Mhz.

cw2 commented 7 years ago

Congratulations @Untitled86 on getting F7 working!

Full disclosure: I am working on NETMF port for NUCLEO-F746ZG board, which should arrive next week...

Regarding the problem with HAL_Time_Sleep_MicroSeconds hanging up, what compiler do you use? Have a look at generated assembly listing and ensure there are THUMB instructions for IDelayLoop function (in IDelayLoop.s) generated and verify jump addresses to have thumb bit set.

LodinErikson commented 7 years ago

@Untitled86 Do you know "STM32CubeMX" software ? Maybe you can compare your settings with the auto generated code.

SytechDesigns commented 7 years ago

@cw2 and any one else interested... did you maybe want to collaborate on the M7 disco port, I do have some\devicecode.. code already : STM32F7_Bootstrap, STM32F7_flash, STM32F7_usart,STM32F7_usb and the processor selector.h etc - most of the other peripherals are compatible with the stmf4 ( I think spi will need some minor tweaks). I do need to check with the 'source' of the code whether it is ok to publically release them, at the moment they are for internal development.

cw2 commented 7 years ago

@SytechDesigns if you have anything that you could share, it would be much appreciated. Although I am not currently focused on the Disco board (targeting simpler Nucleo), obviously the basic components are shared and it would save a lot of work; and also having working reference source code is very valuable.

Thank you in advance.

LodinErikson commented 7 years ago

@SytechDesigns : Sorry but I dont understand what you mean with "M7 disco". Is this a different hardware then the "STM32F746GDISCOVERY" and the "NUCLEO-F746ZG" ? Or the "32F769IDISCOVERY" ? @All Maybe it is better doing a port wich is based on the auto generated files from the "STM32CubeMX" software ?? I really don't know... So much to learn...

piwi1263 commented 7 years ago

Hi Lutz, that's actually a marvelous idea, having STM32CubeMx generate the netmf port software as well. That would certainly boost the use of netmf ... the current process of porting is soo primitive ....

LodinErikson commented 7 years ago

Yesterday I downloaded all(?) files, puzzled about the paths and started to build the STM32f469IDisco and... 147errors :( I had hoped to find a Keil project by using the mdk setting, but nothing. Instead struggling with "msbuild" and 10 lines long commands and a 6MB logfile :( :( Maybe I should go back to my "small" controllers...

cw2 commented 7 years ago

@LodinErikson Have you followed the Getting Started guide? I can build that solution successfully with

setenv_mdk 5.05 C:\Keil\ARM
msbuild Solutions\STM32F429IDISCOVERY\dotnetmf.proj
LodinErikson commented 7 years ago

@cw2 Thanks for your help ! I had 2 problems. 1st : wrong path for CMSIS (not sure) 2nd : I updated Keil to newest Version V5.20 with C-Compiler Version V5.06. With setenv_mdk 5.06 C:\Keil\ARM I got 148 errors :( With setenv_mdk 5.05 C:\Keil\ARM everything is OK, no errors, no warnings :) Someone else should check this. I am a beginner, maybe still my fault...

cw2 commented 7 years ago

@LodinErikson Oh, I see - unfortunately, the version for MDK is a little bit confusing, the current value of '5.05' really means '5.05 and above' (until there are again breaking changes in the toolchain).

Untitled86 commented 7 years ago

Yes, I'm using that for reference. I never sorted out the HAL_Time_Sleep_MicroSeconds problem. Switched to using HAL_Time_Sleep_MicroSeconds_InterruptEnabled and it worked perfectly? I've been moving my beeping and LED flashing code around to see what works. A lot of things ARE working properly. USB isn't one of them. I'm slowly going through the STM32F7_usb_functions.cpp file and comparing it with Cube and others. Hopefully I'll sort it out soon. This manual did mention that the USB wasn't SW compatible, so go figure. http://www.st.com/content/ccc/resource/technical/document/application_note/73/76/21/47/ef/d0/4c/16/DM00164538.pdf/files/DM00164538.pdf/jcr:content/translations/en.DM00164538.pdf

LodinErikson commented 7 years ago

@Untitled86 Any news on your project ?

Untitled86 commented 7 years ago

@LodinErikson - Progress has been slow. So far I haven't been able to get the USB feature working properly.

I don't know how to step through the firmware code running on my device, so I've been using my oscope and toggling some GPIOs to indicate what's happening.

Currently I can see the CPU_USB_Initialize function is running (in my STM32F7_usb_functions.cpp) on bootup. It completes without error, but my USB device doesn't show up on the PC end.

Porting that from the F4 to the F7 required a lot of changes. I used various working USB F7 projects for reference. Most of them were simply renaming constants, but the structs also changed.

My old F4 code had a single struct for the USB feature. OTG_TypeDef. The newer F7 header files have that broken into several structs. USB_OTG_GlobalTypeDef, USB_OTG_DeviceTypeDef, USB_OTG_INEndpointTypeDef and USB_OTG_OUTEndpointTypeDef.

Endpoints in the old code were referenced using an array like this... OTG->DIEP[i].INT = 0xFF; // clear endpoint interrupts OTG->DOEP[i].INT = 0xFF; OTG->DIEP[i].CTL = USB_OTG_DIEPCTL_EPDIS; // deactivate endpoint OTG->DOEP[i].CTL = USB_OTG_DOEPCTL_EPDIS;

In the new code I modified that to use the new structs like this... USB_OTG_IN_EP = ((USB_OTGINEndpointTypeDef) USB_OTG_FS_PERIPH_BASE + 0x900 + (i * 0x20)); USB_OTG_OUT_EP = ((USB_OTGOUTEndpointTypeDef) USB_OTG_FS_PERIPH_BASE + 0xB00 + (i * 0x20));

USB_OTG_IN_EP->DIEPINT = 0xFF; // clear endpoint interrupts USB_OTG_OUT_EP->DOEPINT = 0xFF; USB_OTG_IN_EP->DIEPCTL = USB_OTG_DIEPCTL_EPDIS; // deactivate endpoint USB_OTG_OUT_EP->DOEPCTL = USB_OTG_DOEPCTL_EPDIS;

...I'm not sure if I made a mistake in modifying things, or what. I'm really frustrated at this point.

I also don't know if I'm initializing the clock properly. I've tested my settings by toggling a GPIO at a specific speed (e.g. 1500ms). I then monitored that GPIO using my scope and adjusted my RCC_PLLCFGR_PLLN_BITS, RCC_PLLCFGR_PLLP_BITS and RCC_PLLCFGR_PLLQ_BITS until I got exactly 1500ms on the scope. ...But I wonder if the APB/AHB clock is being initialized improperly.

I'm over my head on this. I'm not giving up, but this is really intense. Any help is appreciated.

cw2 commented 7 years ago

Well, I have TinyBooter and bare TinyCLR for STM32F7, with the obligatory LED blinky application working (USB deployment). There are a few things I have to finish before I can publish it, so please be patient - it will come 'soon' :)

Untitled86 commented 7 years ago

Great news! Thanks!

LodinErikson commented 7 years ago

@Untitled86 I never tried USB-OTG but in the F7 demo was a bug in the USB-Host sources. Here is a post from the ST forum :

there was a post 

 "STMF327-DISCO and "MSC_Standalone" example don't work (Bug in USBH MSC lib v3.2.1)?"

 could not find it at the moment, search engine seems to have problems

 there is a bug in 
 Repository\STM32Cube_FW_F7_V1.1.0\Middlewares\ST\STM32_USB_Host_Library\Class\MSC\Src\usbh_msc.c

 line 446

 change 
 if((phost->Timer - MSC_Handle->timer) > 10000)
 to 
 if((phost->Timer - MSC_Handle->timer) < 10000)

( [https://my.st.com/df56f8d6] )

Untitled86 commented 7 years ago

...Is anyone interested in earning $1,000+ helping me port the F7? If anyone is seriously interested, and capable, my employer is OK with me contracting out some support on this problem. LodinErikson sounds like he's close. Maybe he'd be interested? Of course, LodinErikson is using USB HOST and I need USB OTG (different pins and registers are involved).

LodinErikson commented 7 years ago

@Untitled86 Oh, maybe there is some misunderstanding because of my limited English. It was not me who found this bug in USB-Host.

If you need someone for simple 8051 or STM32 controllers based on Keil, yes I am in. Or better, if you need someone for doing schematics and PCB layout (with Altium) I really can do that. :)

But my skills are not good enough für your USB problem. :( Sorry.

cw2 commented 7 years ago

@Untitled86 https://github.com/cw2/netmf-interpreter/tree/dev-stm32f746nucleo contains a bare STM32F746NUCLEO solution. It is still in an 'alpha' stage, the only working peripherals are GPIO and USB. I have verified GCC build, tinybooter (when active, all three user LEDs are on), application deployment and debugging from Visual Studio.

There are some things (marked with 'UNDONE' and/or 'FIXME' comments) that has to be finished and fixed, I'll most likely update the RAM memory layout in the next commit (move RAM-RW into SRAM2 if it fits, so whole SRAM1 is dedicated to heap). I am now working on serial support...

Note: I am going to publish one or two PRs with fixes required for STM32F7 port separately (i.e. directly to the 'dev' branch), which means I'll most likely rebase dev-stm32f746nucleo branch.

Also, I would like to thank Peter and Justin for their support.

cw2 commented 7 years ago

One important thing I forgot: The USB configuration uses the same VID/PID as other solutions, so the board could show with a wrong name, if there was another board attached previously. To fix that, uninstall the existing USB device in Device Manager and reattach the board.

There is some caching mechanism involved, the ideal/reliable solution is to use different PIDs for different boards or at least an unique serial number. If there is enough interest, I could implement automagic use of the CPU's unique device ID, but IIRC there were certain privacy concerns in the past.

cw2 commented 7 years ago

@Untitled86 Regarding USB OTG, I would first need to have a look at it, no promises at the moment.

Untitled86 commented 7 years ago

@cw2, Peter, Justin and others...

THANK YOU! I have my custom F7 board working now. Our EE configured our board/chip for ITCM instead of AXIM, and we have a 12Mhz external clock. Those were the only things I had to account for with cw's code. I'm now able to see my device via USB!

Untitled86 commented 7 years ago

Adding support for SPI I ran into an interesting problem. The new chip requires you cast the DR register as 8bits when you're attempting to send only 8bits via SPI.

On the F4... spi->DR = out;

On the F7... (__IO uint8_t )&spi->DR = out;

I'll post my code once I'm done testing everything else. But this little issue tripped me up for a day. ...I'm not the C/C++ expert I need to be.

cw2 commented 7 years ago

@Untitled86 Interesting. Although personally I would probably do it the other way round, i.e. to extend the data to match the register size, so it is not accessed unaligned. But, I'd have to check the datasheet and reference code first...

piwi1263 commented 7 years ago

I'm trying too to get SPI working for the F7 but can't even compile. SPI_CR1_DFF not declared in this scope. Anyone has an idea ?

piwi1263 commented 7 years ago

Well found a workaround for the moment. Yet to see if SPI works, at least TinyClr is building, deploying. I included in the STM32F7_SPI_functions.cpp: image

Resulting into reporting back 6 SPI ports.: image

Untitled86 commented 7 years ago

@piwi1263

My bad for not posting code. I have the SPI working here...

https://1drv.ms/u/s!AsDrOapsdMSUk7564f6E9jO_U_wynQ

There may be some features I'm missing. I basically started with the F4 code, but my SPI display etc. are functioning properly with this code.

Note: I did NOT add proper support for all the F7 transfer size options. The chip supports like 4-16bits. The F4 based code I posted only supports 8 and 16bit transfer sizes. And I've only tested the 8bit mode so far.

Also, specifically about SPI_CR1_DFF ...That bit in the CR1 register changed meanings. They were using that to switch between 16 and 8bit mode in the F4 code. Looking at the F4 header files SPI_CR1_DFF is defined as 0x0800 or (0000 1000 0000 0000 in binary). According to the F7 pdf the 11th bit of that SPI_CR1 register is CRCL (CRC Length) bit of that register. If you're using CRC this should be toggled to 1 or 0 if you're using 8 or 16bits.

With the F7 SPI_CR2_DS controls the data size. From 4-16bit. I believe I set that to 0 which is an invalid value that causes the chip to default to 8bit mode.

Untitled86 commented 7 years ago

Any idea what it takes to get the SD card working?

I've added a folder solution\DeviceCode\BlockStorage\SD and populated it with SD_BL_Driver.cpp, stm32f7xx_hal_sd and stm32f7xx_ll_sdmmc (from STM examples). ...Am I headed down the right path?

piwi1263 commented 7 years ago

If you are looking into this on mbed you'll not only find how to support for native ili9341 based displays but how to use the SD card on the display as well. Scroll down until you see Display 3, that's exactly what I have ... https://developer.mbed.org/users/dreschpe/code/SPI_TFT_ILI9341/wiki/Homepage

Untitled86 commented 7 years ago

@piwi1263

Thanks but I'm using a custom board we made with a 2" Sharp Memory LCD. I already had a driver for my display that I wrote back when I was rocking the F4.

I think my problem with the SD card is getting the F7 example code to plugin to the NETMF codebase properly. There are tiny annoying differences. Like the F7 example code reads and writes in 32bit arrays but NETMF uses 8bit arrays. Naturally I'm casting those, and doing everything else I think I need to be doing, but clearly I'm missing something.

Untitled86 commented 7 years ago

@Everybody

SD card working now :)

https://1drv.ms/u/s!AsDrOapsdMSUk757Q3ja_zfpegyoug

You'll also have to modify your TinyCLR, etc. I'm just posting the driver files for now. Hopefully I'll get my entire codebase up soon.

piwi1263 commented 7 years ago

@Untitled86 Too bad your SPI Driver didn't work for me and my ILI9341 Display .... yet

Untitled86 commented 7 years ago

@piwi1263

My bad. I posted the wrong code. One sec.

Untitled86 commented 7 years ago

@piwi1263

Sorry about that. Here's the code I'm using now. I just tested it again and it works great for me. This should work with 16 or 8bits. My display is 8bit so I haven't tested 16bit with a device, but I've seen the output on my scope and it looks right.

Also note, the speed is fixed. Just update the logic around CR1_BR if that's important to you. Soon I'll have that working properly as well.

https://1drv.ms/u/s!AsDrOapsdMSUk758w9KoEEJ51jAa4w

piwi1263 commented 7 years ago

@Untitled86 - That does something but only with some patience and a bit of luck and than ....

image

Updated with your driver, deployed TinyClr, but didn't play at all no flashing LEDs as before and no output either just waiting in the VS deploy window ... then after some time like 30 secs, the display shows up as above and stays for 2 secs and goes blank again ...

Some strange effect is happening, what clock frequency are you running .. ?

Oh, it's time for the fruit show ....

piwi1263 commented 7 years ago

[Update] - now after some minutes reaching the first breakpoint it shows the LCD screen permanently and after continuing the program, the LEDs are flashing again and the LCD stays ... strange behavior ... I guess that's what you get balancing on the bleeding edge ...

[Update2] - After a reset it takes about 3 minutes and 45 seconds to have the display on and before the LEDs are flashing, based upon 216 MHz clock frequency.

[Update3] - And running @192MHz it is pretty much the same time, almost to the second.