STM32, Maple and Maple mini port to IDE 1.5.x

@madius

2 years ago, I tried to use the DF Robot LCD button shield with my Olimexo Maple. I ran into issues and eventually, I found that the (initiation) part of the code was too fast on the 72MHz processor. Here is my thread showing my problems and what I did to get the display to work.

Hopefully, you will be able to get through my explanation.

http://forums.leaflabs.com/topic.php?id=1002

@cycleg, : sadly, this is not the problem, but maybe the next step to keep care about. Fact is, that the MCU freeze or stuck, so no simple serial "hello" or blinky is possible. The code do not get into the main loop or setup.

roger: did you ever tried stm32ld for serial upload? it's with auto dtr(nrst) and rts(boot0)? compiled (win/osx): https://github.com/avikde/koduino/tree/master/stm32/system/stm32ld main repo: https://github.com/avikde/stm32ld looks very convenient for using with FTDI.

OK: I’ve tried out more with liquidcrystal. There is a big common problem!!!
If even one pinMode or DigitalWrite/Read is within a library, the MCU will crash.
I didn’t solved the problem, even included <Arduino.h> <wirish.h> <libmaple/libmaple.h> <libmaple/gpio.h> <pins_arduino.h> <wiring_private.h> and so on.
With energia I solved this problem with #include <energia.h> but I to get a working #include for maple.

This belongs to every pinMode / pinwrite/read library!

Ok, found the error:
They put the pinMode into the constructor!!! This is an awful bad habit involves several years arduino praxis. Even in the official arduino “build a library” tutorial there are pinXXX codes within the constructor.
The reason:
The constructor is called before the main() function which does all the configuration and initialization of the Arduino. So pinMode or digitalWrite isn’t defined at this point. It may work, or it may work not (in this case)

So roger: please update the liquidcrystal library with my modified one!

LiquidCrystal.zip (6.03 KB)

next ported library: EEPROM
get the warning:
/Users/madias/Arduino/BUILD/EEPROM/flash_stm32.c.o: In function FLASH_ErasePage': /Users/madias/Documents/Arduino/hardware/Arduino_STM32/STM32F1XX/libraries/EEPROM/flash_stm32.c:82: warning: undefined reference to ASSERT’
I think the warning is about the erase page. Tried the library out, should be working, but I don’t need it really.
But it’s worth an upload, roger :slight_smile:

EEPROM.zip (13.3 KB)

Hi Matthias

Ok. I will take a look

I think ASSERT is a macro, I did see the code in libmaple somewhere.

Its not very useful, from what I recall I think it was supposed to be able to write a debug message, but it just seems to end up flashing the led

Matthias

Do you mean that the EEPROM.zip you attached is working apart from that warning?

Does it retain the settings after uploading the sketch again, or only survive a reboot ?

I guess I need to test ;-)

BTW. I'm just going to look at

https://github.com/avikde/koduino/tree/master/stm32/system/stm32ld

Thanks

Matthias

https://github.com/avikde/koduino/tree/master/stm32/system/stm32ld didn't work for me

Well, it does upload, but not if you connect DTR and RTS

It appears to pull DTR LOW for the entire upload, which is no good as the docs say that DTR needs to be connected to NRST (which I presume is reset ???) either way, it would just need to be a pulse.

And connecting DTR to BOOT0 would not help as BOOT0 needs to be HIGH when the board is reset.

Actually, I have a feeling I know why it doesnt work.

Some STM32 devices (possibly the one that avikde uses (as he uses and F3) have a feature called "Connect under reset". I know it exists for STLink transfers, but perhaps it also applies to Serial transfers ???

But I don't think that the F103 has this feature.

Also, I checked the RTS pin on my USB to serial and as far as I can tell its not being toggled at all.

Actually, I better double check using my scope just in case its a really short pulse

Either way, its not working for me at the moment !

Ok, so better be on the save side and let the existing one in the repo. It's complicated enough for "new user" so it's not convenient to let the user decide the "try and error" method at several levels (choose board, choose uploader, choose xyz for operation system abc...) I see maybe a problem in my nucleo board.cpp (this maybe also belongs to "maple"): Both use " PMAP_ROW(GPIOA, 3, NULL, 0, ADC1, 3), /* D0/PA3 /" --> PMAP_ROW on maple mini there is a simple {GPIOB, NULL, NULL, 11, 0, ADCx}, / D0/PB11 */ I suspect, this is maybe the error I get with hiddenpilot's UTFT library. It works flawless on the mini (slow and fast) and on nucleo it works only with "fast" (=hardware SPI). The only different between the two boards are the different pin enumeration (or I've missed something) UTFT uses low level pin manipulation like:

#define digitalPinToBitMask(P)     (BIT(PIN_MAP[P].gpio_bit))
#define digitalPinToPort(P)        (PIN_MAP[P].gpio_device)
#define portOutputRegister(P)      (&(P->regs->ODR))

I have made some improvements to the SPIClass class. The “setClockDivider” method needed weird and limiting values (i.e. no way to set a 36 Mhz clock for SPI 1) and the “transfer” and “write” methods were not waiting for the SPI busy flag to be cleared. I also added a “setFrequency” method.

SPI.setClockDivider(SPI_CLOCK_DIV2) gives you the fastest clock, 36 Mhz (SPI 1) or 18 Mhz (SPI 2)

SPI.setClockDivider(SPI_CLOCK_DIV256) gives you the slowest clock, 281.250 Khz (SPI 1) or 140.625 Khz (SPI 2)

SPI.setFrequency(SPI_36MHZ) gives you a 36 Mhz clock (only supported by SPI 1)
SPI.setFrequency(SPI_18MHZ) gives you a 18 Mhz clock

SPI.setFrequency(SPI_281_250KHZ) gives you a 281.250 Khz clock
SPI.setFrequency(SPI_140_625KHZ) gives you a 140.625 Khz clock (only supported by SPI 2)

SPI.patch.txt (8.52 KB)

Fix for non-working hardware initialization in HardWire class constructor.

HardWire.patch.txt (777 Bytes)

Some libraries interact with the "Serial", "SPI" and/or "Wire" instances. What they represent is currently fixed. Why not let the user choose? Good idea? Or not?

Tim

If you pick the Generic board type that Alexey (@hiddenpilot) created, it already has a load of menus.

I'm not sure that adding another 3 menus would suit most people, and I'm not sure how complicated the boards.txt would be to implement all these menus.

Perhaps there is some better way of writing the boards.txt to handle all these menus, but at the moment it looks like a lot of authoring needs to be done for each menu. E.g. It doesn't look, like you can simply set one variable per menu.

However there may be some way to change platform.txt or possibly do something with #if s in the code to allow boards.txt to be simpler.

Also, there are bugs in the way boards.txt is handled by the IDE. If you look at Alexey's. Generic board type, you will see its called Nano. This is because the only way he could get it to work was to give it a name of an existing core Arduino device.

As the IDE team are still working on 1.6 I think we should urgently see if we can get this fixed and also see if somehow we can improve the menu handling in boards.txt

It may be worth sending a PM to @hidden pilot to get his opionion and experiemces on making big modifications to boards.txt

I think we need to follow the 80 20 rule, I.e not over complicate the process for the 80 of people who just want to use a standard Maple mini etc Those who have complex requirements should have the skill to change what they need.

rogerClark: If you pick the Generic board type that Alexey (@hiddenpilot) created, it already has a load of menus.

I'm not sure that adding another 3 menus would suit most people

They don't need to pick anything, the default (top option?) can be the currently hardcoded behaviour.

rogerClark: and I'm not sure how complicated the boards.txt would be to implement all these menus.

You need 3 extra lines and a blob of settings (copy/paste/modify) for each board you want to have the settings.

rogerClark: Perhaps there is some better way of writing the boards.txt to handle all these menus, but at the moment it looks like a lot of authoring needs to be done for each menu. E.g. It doesn't look, like you can simply set one variable per menu.

I can have all boards support the SPI/Serial/Wire options in 15 minutes. Copy/paste/modify. Not a lot of work.

rogerClark: However there may be some way to change platform.txt or possibly do something with #if s in the code to allow boards.txt to be simpler.

The menu options add certain defines to the gcc/g++ commandlines. The necessary code to support the "Wire" options looks like

#ifdef MAP_WIRE_I2C_1
HardWire Wire(1, 0);
#endif

#ifdef MAP_WIRE_I2C_2
HardWire Wire(2, 0);
#endif

#ifdef MAP_WIRE_PB6_PB7
TwoWire Wire(PB6, PB7, SOFT_FAST);
#endif

rogerClark: Also, there are bugs in the way boards.txt is handled by the IDE. If you look at Alexey's. Generic board type, you will see its called Nano. This is because the only way he could get it to work was to give it a name of an existing core Arduino device.

As the IDE team are still working on 1.6 I think we should urgently see if we can get this fixed and also see if somehow we can improve the menu handling in boards.txt

I know of a better way to make it work, don't use underscores. Works perfectly. Naming boards after Arduino ones also works but might cause preferences.txt issues.

rogerClark: It may be worth sending a PM to @hidden pilot to get his opionion and experiemces on making big modifications to boards.txt

No need, I already have it working locally. Guess I'll keep my changes to myself then :(

rogerClark: I think we need to follow the 80 20 rule, I.e not over complicate the process for the 80 of people who just want to use a standard Maple mini etc

The default behaviour (i.e. don't touch the menu options) will still be the same.

rogerClark: Those who have complex requirements should have the skill to change what they need.

Maybe they should start their own GitHub repo? :)

Hi tim

I'm not against adding loads of functionality, I'm just cautious about over complicating it for new users

Please share your changes.

Matthias,

Thanks

I've updated the LiquidCrystal library with your files, but I don't have a way to test this, so it would be good if someone else could confirm it works for them. e.g. Alexey ??

Also...

I've updated the EEPROM library, and then fixed the issue with the missing definition of ASSERT, by including libmaple/util.h

I also updated the example to call serial.begin as its only Maple boards that don't need this, (and its ignored if its a Maple or Maple mini) and I happened to have my generic STM32 board connected, hence the example didn't work for me.

I also looked at stm32ld again, but on my Mac, and it still doesn't work. I've also looked at the other signal lines on my oscilloscope and it doesnt toggle RTS on my Silicon Labs USB to Serial device.

I know @John1993 is using an uploader that does reset the board OK, but doesn't attempt to toggle boot0, and it works fine for him. So it may be worth updating stm32flash or using this stm32ld with modifications to reset the board.

I also noted that in the readme for stm32ld it still mentions that Boot0 must be manually pulled high, so either the readme has not been updated or the code hasn't :-(

I guess I could post an issue to find out if Avik is actually using this or not.

@Tim

I will process your patches later. I've not had time to do your changes after doing Matthias's changes.

Thanks to both of you for adding to the greater good ;-)

timschuerewegen: No need, I already have it working locally. Guess I'll keep my changes to myself then :(

Here is my take on the nested menu methodology: The problem I have is that the settings metadata is NOT stored in the sketch file(s). This is a real pain in my ass when I pull up an existing file and have to reset menu options, etc. I would far prefer a radio-button kind of interface like the fused calculator interface with one line of HEX metadata stuck in the main INO as a // comment.

Even with the limited 1.6.0 nested stuff, I have screwed up more than 1 compile and download. More nesting is just going to be more complexity and I am somewhat familiar with the system!!

Yes, it looks simple; it is simple; but there are too many simple little tweeks to set-up to be really simple.

Opinion by,

Ray

mrburnette: The problem I have is that the settings metadata is NOT stored in the sketch file(s). This is a real pain in my ass when I pull up an existing file and have to reset menu options, etc.

If you select "Serial -> none", "SPI -> none" and "Wire -> none" then no instances of the SPIClass, TwoWire//HardWire and USBSerial/HardwareSerial classes are automatically created. If you then want to use a library which references "Wire", you simply place a "HardWire Wire(1,0);" or "TwoWire Wire(PB6, PB7, SOFT_FAST);" in your sketch.

Ray,

Thanks for that insight.

I can see all sorts of support questions to the forum if we implemented this, saying xxx example doesn't work, i.e because they've not set the correct menu settings.

If switching of SPI and I2C need to be done at all, I think its safer either to call the constructor yourself, or if the intention is to force a third party library to use alternative hardware - which seems quite a niche request, the better option would be to have a #define in the top of the main sketch to change the master SPI or I2C settings.

e.g.

define USE_I2C_CHANNEL 2

or something similar

which could be tested for in the Wire or SPI classes etc