Support for STM32 Nucleo?

Posted on
Page
of 2
/ 2
Next
  • I think you should offer a premium version of the Espruino IDE for $4.99 on the chrome store. This premium version would have support for the STM32 Nucleo and Discovery series boards with 256k or more. I would like support for the stm32F401RE specifically, but many of them would work well with Espruino.

    I would buy the espruino, but I would need to solder some female headers on, and I would need to re-write code to work with my Arduino shields. This way way you get some money, and I don't need to buy another board when I already have 10 similar boards. I would also work on this for free if you wanted to give me some guidance on how to get other hardware to be compatible with the Espruino IDE.

  • Hi - thanks for the suggestion... It's quite a good idea to have a way to maybe do an 'in-app purchase' to get support for other boards.

    However the work that needs to be done is not in the Web IDE, it is in the Espruino firmware which goes onto the board. Once that is done it'll work on the Web IDE without any changes required.

    The issue really that everything is Open Source, so if I were to add any restrictions to the Web IDE or Firmware then someone would just copy it, remove the restriction, and put it online elsewhere. I did try a donate button in the past, but so few people used it that it wasn't worth having - I guess I could try something a bit more obvious - like Ubuntu's download button.

    It's kind of a hard situation - I got given a very hard time for not being Open Source before the KickStarter, but now I am Open Source it makes it difficult to do things that might actually be in everyone's best interests.

    Anyway, I'm sure you'll find other rants from me about it on the site :) If you do want to try and port to the Nucleo yourself, it shouldn't be too painful.

    There's some info here: https://github.com/espruino/Espruino/blo­b/master/README.md

    Basically you need to get your computer set up so you can build Espruino for ARM, then you just create a new file boards/NUCLEO_F401.py with all the pins written in it and copy/paste a few lines in the Makefile. It shouldn't be that difficult.

  • Thanks for your quick response. I should have read the readme.md on github first. I did not expect such clear, detailed , support in the readme file. You really have a great company that is doing great things, so thanks again.

  • Hello,

    I have started some development around the NucleoF401RE board and Espruino 1v71.
    However, it is just not even to an alpha status so far: console on UART2 works, LED1 blinks, BTN1 reads correctly but setWatch and save() don't work yet, memory was left to an other board default values. Meanwhile writing this suggests me some clues...
    Actually, it is more an approach to get some more RAM/Flash, use some ready made arduino's shields and potentially be able to do some step by step debugging with EmBlocks. It comes with the Nucleo support out of the box too and mbed exports to it since last week.

    So contributing to the Espruino interpreter project is my intention.
    Incidently, should I create a separate branch in the Espruino project and submit my commits to this branch? I read something somewhere about contributing: finding it again is uneasy.

    I definitively will not attempt to provide a serious/permanent support for this board...

    Linked file is a rough log, all keystrokes included, of a session with gtkterm... Still have to try Web IDE for instance.


    1 Attachment

  • Hi, that's great news!

    Strange that setWatch doesn't work though - the 401 chips I've been using here seem to work ok with it.

    To contribute back, just issue a pull request on GitHub (using a branch means you can do other stuff on your repo without modifying the pull request as time goes on). As long as the changes don't impact other boards I'll try and pull them in. If you could update the readme with the state of the board's support it'd be really handy though.

    thanks!

  • Hi, in fact what might impact others boards is mainly:

    1-modified: ./Makefile
    Where i added a NUCLEOF401RE section in order to get it working. By the way I had to create an uncommented line like "NUCLEOF401RE=1" in order to build correctly otherwise "BOARD=NUCLEOF401RE make" was always building for a LINUX configuration... I am wondering how to do a proper selection with "BOARD=NUCLEOF401RE make" without having to have a "NUCLEOF401RE=1" line predefined in the Makefile. Something unusual must happen in my system.

    2-modified: ./scripts/build_platform_config.py
    Where I had to use os.path.normpath otherwise neither "/../scripts" nor "/../boards" where correctly interpreted and I had a "module not found error" immediately at the import line. This change should not do anything to other boards since it is a standard python functionality for normalising path and file names. I also added a leading line "# -- coding: utf8 --" because my comments included some accentuated letters.

    Everything else is actually new files added under ./boards/ subtree.

    So, I think my changes are harmless for other boards while my additions should also be harmless although unreliable so far. No C code was written or modified...

    By the way I found the contributing.md file which explains your requirements.

    Two questions:
    a- How do I compute the memory values used in the boards .py files under the 'saved_code' section and for the 'variables' under the 'info' section? I copied the values from the STMDiscovery file just changing the memory sizes according to the STM32F401xE manual.

    b- The NUCLEO boards do have an hybrid connectivity which creates a conflict about pin names: Arduino's analog inputs are names A## and the Espruino names are also A## to H##. You, logically, shortened the names as defined in the STM32F401 manuals by removing the leading "P". This makes A1, for instance, a valid name for both standard naming rules although the actual pins positions and functionality are totally different. Do you have any suggestion about how to name the Arduino's pins and the Nucleo's pins without breaking the already applied rules for the different boards?

    I am also surprised that, for instance, setInterval works perfectly while setWatch doesn't at all. Actually holding down the user button is correctly read ("analogRead(BTN1)" answers 0 if pressed down, 1 if not pressed). Or is it a reversed logic problem when compared to Espruino board's user button?

    I confirm that save() won't make it although the console log shows that it did it correctly. A "reset()" followed by a "dump()" won't show anything saved.

    Finally, the web IDE works correctly. I just have an other problem with a character left in the input buffer whenever a reset() is done. This a firmware problem not a web IDE problem.

    Next step is a git pull request directly on your GitHub repo.

  • Thanks!

    Best bet is to build with NUCLEOF401RE=1 make - that's what I do (and suggest in the README afaik).

    Variables are 16 bytes each and I usually leave 12k for stack/etc, so (96-12)*1024/16 = 5376 for variables. saved_code is to do with page sizes (because on the 401xC chips you have to use the 16kB pages right in the middle of memory). As you have a bigger chip you can afford to just use the 128kB page right at the end of memory, so just delele the whole 'saved_code' section and it should automatically use the last page. Maybe check that it seems to be doing that inside the platform_config.h file that's generated.

    Honestly I'm not sure about pin names. I'd maybe suggest trying to code in 'AA0..AAx, and AD0..ADx?' it's a bit of a pain though as that's all done with code.

    And yes, I guess the button is inverted - on the Espruino board it reads 1 when pressed.

  • Thank you!
    I confirm that digitalRead(BTN1) answers 1 with button not pressed.
    I will try the new values for memory and sizes by tomorrow.

    Pin names are a limited problem, I just choosed to use the Espruino's naming convention even for the Arduino's shield connections. This is just an arbitrary choice because finally it complies with the other ST boards and allows for a greater compatibility with Espruino itself. Using the Arduino's pins names would just create complex situations.

    This is yet to be definitely decided anyway. Any suggestion such as yours will be welcomed: it has to be simple to remember.

    Did my very very first git pull worked correctly?
    Discovering Travis is just the next step about continuous integration.

    Congratulation for the Espruino Pico founding, I guess I am one of the super early birds.

  • Thanks for supporting the Pico!

    Yes, the GitHub pull worked great!

    You could implement the Arduino pins as Arduino.A7 etc. It would just be a matter of creating a jswrap_nucleo.c file that added the relevant constants...

  • Hello,

    a- So I have tried to have save() working properly.
    Obviously, my parameters in NUCLEOF401RE.py where uncoherent.
    However, it is still failing at check time: I guess, there is a question of page size which is non constant on higher addresses of the flash memory on the STM32F4 series. This results from the STMF4 programming manual RM0368 Reference manual table 5 page 45/835.
    It is a constant, 2K bytes, on the STM32f1 series as written in table 4 page 8/31 of PM0075 Programming manual so the code of jshSaveToFlash() is somehow simplified about this point...
    I added some jsiConsolePrint here and there. Which helped me but did not changed the logic of this routine in any way.
    The micropython's equivalent routine seems to use a pre computed table to determine the page size out of the flash's base address to be written. They use a STM32F4...
    Changing anything in this area of the code could, potentially, be a real problem since I can't test other boards.

    b- I changed the definition of BTN1 with

    'BTN1' : { 'pin' : 'C13',
                 'inverted' : True,
                 'pinstate': 'IN_PULLUP', # to specify INPUT, PULL_UP
               }
    

    No further investigation about it and setWatch()

    c- The Arduino's connectors pins names will probably end up the an "Arduino." prefix as you suggested. mbed names are totally incompatible with Espruino conventions. Yet, those arduino's connectors pins are just straight connections to the standard Nucleo connectors: I think it could just be aliasing Arduino's names to Espruino's names...

    So far nothing else, I am focused on save() problem.
    This is an important function to get an Espruino firmware useful on the Nucleo.

  • save()

    So page sizes on F4xx chips go: 16,16,16,16,64,128,128,128

    As you have enough flash, you just want to stick code at the end in a single 128kB page (like for the F4DISCOVERY). I think using the py file arrangement from that (Eg, no saved_code structure) should 'just work'.

    You can always use peek32 to check if the code is in the correct place after saving it.

    I think it could just be aliasing Arduino's names to Espruino's names...
    Yes, I think that's all you'd want to do.

  • Hello,

    About page sizes:
    There are some details from ST doc: The 2 upper pages have to be unlocked with a specific value for these sectors.
    The reference manual, chapter 3.8.6 page 63/835 Flash option control register (FLASH_OPTCR), bits nWRP[7:6] shows a specific context which is somehow unclear to me.
    I was wondering if the stmhal library does care about those bits or not?

    Also, I tried the F4DISCOVERY values and did not had success: Apparently, the magic word address was right in the middle of the sector 6 which also contained the saved values.
    I think, it is a matter of page size (tried only 16K while it probably should be 128K) and number of pages (tried 3 while it again probably should be 2).
    So I have to spend more time on that point.

    As a side point, you can get:
    a- the size of the flash incorporated to your STM32 by peeking address 0x1FFF 7A22, value in KiloBytes, see page 829/835. This could be used to determine what special tweaks have to be done, depending upon the sector to be programmed / erased.
    b- a unique id, 96-bit long, of the stm32 by peeking at address 0x1FFF 7A10

    Do you use any of those already?

    That's all for today...

  • Hi, Thanks for all your work on this!

    Yep - I use the ID if you look at process.env, although I don't tend to use the flash size as generally Espruino is compiled for a specific size chip.

    Personally I'd have thought that there should be a single, 128kB page. Actually I seem to recall that there was a hack for the F4 board where I set the flash size at less flash than the board has in order to work around something - which might be the second unlock value (I could be remembering wrong though).

    I've posted in another thread, but as part of helping me get better chips for the Espruino Pico KickStarter, ST would like me to get the Nucleo 401 working and to put binaries for it on the Espruino website. That means I'll have to sort out the flash/setWatch problems soon anyway - so if you'd rather not spend time on it don't worry too much :)

  • Hi,

    Setting up NUCLEOF401RE.py with my suggested parameters doesn't work yet:

    • addresses are correct now and writing happens without any apparent glitch,
    • errors happen after the control of the 8'th byte read, just as if something had not been waiting correctly before writing there. Could be a question of latency: 84 Mhz is far more than the 48 Mhz of Espruino board.

    I still have no luck with setWatch: just no reaction to BTN1.

    Having help from ST is definitely the best thing you could have.

    Reading the docs shows they have been gradually expanding their variety of products and added some register's tricks incrementally too. As a result, each model of STM32F has its own particularities.
    I think you should consider using the updated stm32_hal libraries as they include new functions and correct bugs every other month apparently.

    So I'll try again but not so often as I expect some clean solutions on your side: You have 15 weeks to solve those things. Don't you?

  • Hi - I don't think it's going to be a problem with the flash writing, as this all works on the F401CC (in the Pico) and the F401VC (in the discovery board), which are going to be almost identical.

    I'll get a 401 nucleo on order - but for now, you could just set the RAM and Flash size down, and copy the code from https://github.com/espruino/Espruino/blo­b/master/boards/STM32F401CDISCOVERY.py - that would at least get save working, although you'd just have a bit less memory available.

    As far as the libraries - I believe these are as up to date as you can get without changing to the STM32 Cube libraries - and doing that is going to require some very serious changes. I haven't encountered any bugs in the libraries for any of the supported chips, so rewriting a bunch of stuff to move to the new libraries is only likely to cause bugs rather than fix them!

    Hopefully I'll have something working on that board in the next few weeks - as it's almost the same chip as the Pico it shouldn't be too hard.

  • Hi,

    So, I pushed some changes to NUCLEOF401RE.py that do it for save(). There is no need to update the libraries and yes, I think that would be a lot of rewrites for the substantially little or none benefits.
    Now save() resists even if you reflash Espruino interpreter itself. That's because the save() is done to the last page of the flash memory. This page is not erased when you flash the firmware.

    In order to use a lower flash size F4 series you just have to follow my comments in this file.
    On the other hand, flashing a NUCLEOF411RE would imply deeper changes because it has 192 Kbytes of RAM separated in 2 non adjacent memory areas.

    Now I am trying to see how to have setWatch work:

    >reset()
    =undefined
     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v71 Copyright 2014 G.Williams
    >ÿ
    =undefined
    Uncaught SyntaxError: Got ?[255] expected EOF
     at line 1 col 1
    ÿ
     ^
    >dump()
    =undefined
    >load()
    =undefined
    Loading from flash...
    >þ
    =undefined
    Uncaught SyntaxError: Got ?[254] expected EOF
     at line 1 col 1
    þ
     ^
    >dump()
    =undefined
    >load()
    =undefined
    Loading from flash...
    >dump()
    function buttonWatcher() {
      console.log("Pressed");
      digitalWrite(LED1, Math.random()>0.5);
    }
    setWatch(buttonWatcher, "C13", { repeat:true, edge:'both', debounce : 100 });
    =undefined
    >process.memory();
    ={ "free": 5320, "usage": 56, "total": 5376, "history": 31,
      "stackEndAddress": 536958516, "flash_start": 134217728, "flash_binary_end": 134442916, "flash_code_start": 134610944, "flash_length": 524288 }
    >process.env
    ={
      "VERSION": "1v71",
      "BUILD_DATE": "Nov  6 2014",
      "BUILD_TIME": "09:23:40",
      "GIT_COMMIT": "f8d8135ec74c5539669ca594165876cfba03b66­f",
      "BOARD": "NUCLEOF401RE",
      "CHIP": "STM32F401RET6",
      "CHIP_FAMILY": "STM32F4",
      "FLASH": 524288, "RAM": 98304,
      "SERIAL": "56005b00-0b513333-37343534",
      "CONSOLE": "Serial2"
     }
    >digitalRead(C13);
    =1
    >digitalRead(C13);
    =0
    >setWatch(buttonWatcher, BTN, {edge:"both", repeat:true, debounce: 100});
    =2
    >clearWatch(2);
    =undefined
    >clearWatch(1);
    =undefined
    >dump()
    function buttonWatcher() {
      console.log("Pressed");
      digitalWrite(LED1, Math.random()>0.5);
    }
    =undefined
    >buttonWatcher()
    Pressed
    =undefined
    >buttonWatcher()
    Pressed
    =undefined
    >buttonWatcher()
    Pressed
    =undefined
    >buttonWatcher()
    Pressed
    =undefined
    > save()
    =undefined
    Erasing Flash....
    Programming 86016 Bytes...................................­........................................­............
    Ãhecking...
    Done!
    >þ
    =undefined
    Uncaught SyntaxError: Got ?[254] expected EOF
     at line 1 col 1
    þ
     ^
    > 
    

    I just pressed and hold down button BTN1 between last 2 digitalRead(C13)...
    Apparently, the setWatch is correctly recorded when defined, dumped correctly but never launched.

    This code was loaded from flash and so the answer when defining setWatch is 'undefined' but actually, it return the integer number that identifies the setWatch for the clearWatch.
    As shown, buttonWatcher does its job correctly, the led changes randomly.
    So both of those functions works but the interrupts are not generated.

    Arduino's pin renaming is still in progress.

    There is a parasitic character in the input buffer after a reset(), a save() or a load(). This is not a big issue but still preventing some reloads or reset before programming from the web IDE. Its code is 0xFE or 0xFF.

    Also, I expect some difficulties with UART6 which I intend to use one day. There is FIXME somewhere is the code about it.

    Have a nice day and congratulation for the Espruino Pico, you not so far away to get £50000 founding level.

  • Thanks for all your work on this!

    Have you tried setWatch without the debounce? Does the value from getTime keep incrementing? It's possible there's actually a problem with the RTC and the time is stationary, which is why it's not calling the callback.

  • Just checked up on the NUCLEOF411RE - are you sure about the 192kB? Everything I can see from ST's site and the reference manual implies it's got a single chunk of 128kB.

  • Sorry, I got confused with STM32F4DISCOVERY which has 192 kB.
    Still it is an interesting product.

  • Yes, I posted only the last results:
    a- debounce doesn't change anything (0 or 100 or 200 ms). It all seems that the code is just never launched: I launched buttonWatcher() manually to check it works per itself but actually I never saw its messages when pressing the button. When set to 0 it is not displayed in the dump().
    b- as a consequence I can't say if getTime keeps incrementing in that function. I removed the e parameter in order to check manually because I don't know how to feed the event time outside of the setWatch. Meanwhile getTime() does run correctly from the prompt and keeps counting from the power on moment.

  • Ok, I just got a Nucleo and tested this... I've just added Nucleo.D0/etc if you want to try it out.

    It turns out that setWatch does work, but only on Port A. BTN1 is on C13 which is why it wouldn't go. I'll try and fix that this afternoon - it shouldn't be too difficult to sort out.

  • Ok, I take that back - it's not quite that simple :)

  • Phew, nope - it was that simple. SYSCFG registers weren't powered up, so weren't taking the values that were being put into them.

    If you pull from GitHub it should be fixed now.

  • Congratulations: Now BTN1 and setWatch do work!!!

    Connected
    >
    =undefined
    >echo(0);
    Uncaught [object Object]
     at line 1 col 9
    console.log("<<"+"<<<"+JSON.stringify(pr­ocess.env)+">>>"+">>...
             ^
    =undefined
    >
    =undefined
    >reset(!;
    =undefined
     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v71 Copyright 2014 G.Williams
    >ÿecho(0);
    =undefined
    Uncaught SyntaxError: Got ?[255] expected EOF
     at line 1 col 1
    ÿecho(0);
     ^
    >function buttonWatcher() {
    :  console.log("Pressed at "+getTime());
    :  digitalWrite(LED1, Math.random()>0.5);
    :}
    =function () { ... }
    =undefined
    >setWatch(buttonWatcher, BTN, {edge:"both", repeat:true, debounce: 0});
    =1
    >echo(1);
    =undefined
    Pressed at 31.86450067857
    Pressed at 32.05031824999
    Pressed at 33.17640026190
    Pressed at 33.34058927380
    >dump()
    function buttonWatcher() {
      console.log("Pressed at "+getTime());
      digitalWrite(LED1, Math.random()>0.5);
    }
    setWatch(buttonWatcher, "C13", { repeat:true, edge:'both' });
    digitalWrite(A5,1);
    =undefined
    >a=3
    =3
    >save()
    =undefined
    Erasing Flash....
    Programming 86016 Bytes...................................­........................................­............
    Checking...
    Done!
    >reset()
    =undefined
     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v71 Copyright 2014 G.Williams
    >dump()
    =undefined
    >load()
    =undefined
    Loading from flash...
    >dump()
    function buttonWatcher() {
      console.log("Pressed at "+getTime());
      digitalWrite(LED1, Math.random()>0.5);
    }
    var a = 3;
    setWatch(buttonWatcher, "C13", { repeat:true, edge:'both' });
    digitalWrite(A5,1);
    =undefined
    > 
    

    The remaining problems are now:

    1. a parasitic character in the input buffer. Which creates those strange errors "Uncaught SyntaxError: Got ?[255] expected EOF"
    2. I have to check UART6 and more details on I/O.

    Just a complement about Nucleo boards:
    A- port A: the ST-LINK/V2-1 is using some of its pins to debug and program as mbed needs it.

    1. PA2 and PA3 are the USART2 console TX/RX.
    2. "PA13 and PA14 share with SWD signals connected to ST-LINK/V2-1, it is not recommend to
      use them as IO pins if ST-LINK part is not cut."

    B- power supplied from USB port: there is the negotiation between the host and the Nucleo that happens at boot time. If there is no agreement from the host, the Nucleo will only use 100 mA from the USB port. This happens when the Nucleo is powered from an USB power supply. The jumper JP1 determines that (manual UM1724 page 17/54). This could also be a trap when more power is required at boot time or later.

    C- various default solder bridges change a lot of details around the pins potential usage.

    Again thank you for supporting an "unofficial board".

  • I can confirm this also works for the STM32f411RE! the 411 has 100mhz and 128 kb sram, so it is a bit more powerful. Making a few changes would be better, but the stm32f401re.bin file does work with the slightly more powerful 411 MCU. The st link software is not as happy when programming; it disconnects and sends an error after. But it does work, and connects to the IDE with no problems. So I am happy! Thanks asez73!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Support for STM32 Nucleo?

Posted by Avatar for ac413 @ac413

Actions