Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Board STM32G031J6, issues with starting the downloaded code (pinMode hangs) #1637

Closed
olikraus opened this issue Jan 30, 2022 · 47 comments · Fixed by #1653
Closed

Generic Board STM32G031J6, issues with starting the downloaded code (pinMode hangs) #1637

olikraus opened this issue Jan 30, 2022 · 47 comments · Fixed by #1653
Assignees
Labels

Comments

@olikraus
Copy link
Contributor

Please, before reporting any issue

  • Make sure you are using the latest Arduino_Core_STM32 version.
    https://github.com/stm32duino/Arduino_Core_STM32/releases/latest
    Oliver: I have installed Arduino Core STM32 last week (2.2.0)
  • Make sure the issue is not already reported/fixed on GitHub or discussed on the stm32duino forum
    Oliver: I have looked for similar problems for STM32G031 but the total number of entries for the STM32G031 is very much limited and do not fit to my case
  • Submit a GitHub issue only for reporting a problem related to the Arduino_Core_STM32.
    Oliver: Difficult to say, but I assume it is a problem within Arduino_Core_STM32
  • Avoid to submit a GitHub issue for project troubleshooting.
    Oliver: I have partly modified Arduino_Core_STM32 as a workaround (see below) and my project is just the Arduino "blink" example.

Any questions/feedback/suggestions should be discussed on the stm32duino forum:

⚠ When reporting any issue, please try to provide all relevant information to help on its resolution.

Describe the bug

  1. After successful upload, the code (Arduino Blink) is not executed by STM32CubeProgrammer (Running the code after upload does not work)
  2. After hardware reset, the code (Arduino) is not executed

To Reproduce

Steps to reproduce the behavior:

  1. Open the Arduino Blink example
  2. Upload the Arduino Blink example
  3. Check whether the LED blinks
  4. Reconfigure target to execute the newly flashed code
  5. Execute a hardware reset on the target
  6. Check whether the LED blinks

Note: I will provide more information with partial findings below in this issue

Expected behavior
The code should be executed from STM32CubeProgrammer and after hardware reset

Screenshots
Here is the protocol of the successful upload (I can provide more screenshots on request)

sh /home/kraus/.arduino15/packages/STMicroelectronics/tools/STM32Tools/2.1.1/stm32CubeProg.sh 1 /tmp/arduino_build_310859/Blink_stm32g0.ino.bin ttyUSB0 -s 
      -------------------------------------------------------------------
                        STM32CubeProgrammer v2.9.0                  
      -------------------------------------------------------------------

Serial Port ttyUSB0 is successfully opened.
Port configuration: parity = even, baudrate = 115200, data-bit = 8,
                     stop-bit = 1,0, flow-control = off
Activating device: OK
Board       : --
Chip ID: 0x466 
BootLoader protocol version: 3.1
Device name : STM32G03x/STM32G04x
Flash size  : 64 KBytes (default)
Device type : MCU
Revision ID : --  
Device CPU  : Cortex-M0+

Memory Programming ...
Opening and parsing file: Blink_stm32g0.ino.bin
  File          : Blink_stm32g0.ino.bin
  Size          : 10332 Bytes
  Address       : 0x08000000 

Erasing memory corresponding to segment 0:
Erasing internal memory sectors [0 5]
Download in Progress:

File download complete
Time elapsed during download operation: 00:00:01.626

RUNNING Program ... 
  Address:      : 0x8000000
Start operation achieved successfully

Desktop (please complete the following information):

  • OS: Ubuntu Linnux
  • Arduino IDE version: 1.8.19
  • STM32 core version: 2.2.0
  • Tools menu settings if not the default: [e.g. Newlib Standard, No Serial]
    • Board: Generic STM32G0 series"
    • Board part number: Generic G031J6MX
    • USART support: Enabled
    • C Runtime Library: Newlib Nano (default)
    • Upload method: STM32CubeProgrammer (serial)
    • Port: /dev/ttyUSB0

Board (please complete the following information):

Additional context
LED at PA13 (pin 7 of the SO8N )
I assume pin 7 of the SO8N can be accessed by Arduino pin number 6 (

)
So my initial code looks like this (didn't execute):

#define MYPIN 6

void setup() {
  pinMode(MYPIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
  digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Bypassing pinMode and digitalWrite

To debug this, I have bypassed pinMode and digitalWrite:

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
    //pinMode(MYPIN, OUTPUT);
  GPIOA->MODER &= ~GPIO_MODER_MODE13;  /* clear mode for PA13 */
  GPIOA->MODER |= GPIO_MODER_MODE13_0;  /* Output mode for PA13 */
  GPIOA->OTYPER &= ~GPIO_OTYPER_OT13; /* no Push/Pull for PA13 */
  GPIOA->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED13; /* low speed for PA13 */
  GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD13; /* no pullup/pulldown for PA13 */
  //GPIOA->BSRR = GPIO_BSRR_BR13;   /* atomic clr PA13 */
  GPIOA->BSRR = GPIO_BSRR_BS13;    /* atomic set PA13 */
}

// the loop function runs over and over again forever
void loop() {
  //digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    GPIOA->BSRR = GPIO_BSRR_BS13;    /* atomic set PA13 */
  delay(1000);                       // wait for a second
  //digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
    GPIOA->BSRR = GPIO_BSRR_BR13;    /* atomic clr PA13 */
  delay(1000);                       // wait for a second
}

This code is also not executed, however if -DUSER_VECT_TAB_ADDRESS is used as compiler arguments, then the code gets executed successfully.

I have added this dlag to

compiler.extra_flags=-mcpu={build.mcu} {build.flags.fp} -DUSE_FULL_LL_DRIVER -mthumb "@{build.opt.path}"
like this:

compiler.extra_flags=-mcpu={build.mcu} {build.flags.fp} -DUSE_FULL_LL_DRIVER -mthumb "@{build.opt.path}" -DUSER_VECT_TAB_ADDRESS

This will at least start the above code (blink works), however:

  • any call to pinMode() will again crash the code
  • Startup of the code via hardware reset still doesn't work (this means: STM32CubeProgrammer can start the code, but HW reset still doesn't work).

To me it looks like that SCB->VTOR is not setup correctly during startup for the STM32G031.
But there is another bug, because pinMode() still does not work and crashes the code.

Summary

  • Everything works if only delay() is used and SCB->VTOR is assigned correctly
  • A call to pinMode() will halt/crash the code
@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 3, 2022

Hi @olikraus,
Thanks for your detailed description.
I tried to reproduce your issue, but I have several concerns:

  • I did not succeed to flash STM32G031J6 with USART(Pin5/6) of my STM32G0316-DISCO.
    According to AN2606, USART1 bootloader is available on PA9/PA10.
    but on SO8N, PA9/PA10 are not available, but rather PA11/PA12 (Pin5/Pin6).
    eventually, stm32g0 has the capability to remap PA11 so that it operates like PA9 (and similarly remap PA12 to operate like PA10).
    I am not sure that bootloader is able to manage this remap (enquiry ongoing).
    So my hypothesis, is that I have an old bootloader which was not able to manage remap, and you have a recent one, which manage the remap. To be confirmed.

  • I made some tests with my Nucleo-G031k8. It is the same, i cannot flash over USART with remap pin PA11/PA12.

  • But on this Nucleo-G031k8, PA9/PA10 are available. So I continue testing with PA9/PA10.
    As I understand, you initially clear option byte nBoot_SEL with you own program so that Boot0 pin is effective (instead of nBOOT0 option byte) and similarly you also disabled NRST pin by setting NRST_MODE= b10 in Option Bytes.
    In your sequence to reproduce this issue, you said:
    4. Reconfigure target to execute the newly flashed code
    Do you mean switch Boot0 pin from logical 0 to 1 ?
    5. Execute a hardware reset on the target
    As you deactivated NRST pin, you could not just act on this pin, so did you power OFF/ON instead ?
    On my side, BOOT0 pin is hardly accessible, so instead I used option Byte nBOOT0.
    So I configured it to run bootloader (nBOOT0=0). I upload the blinky Arduino sketch through usart, and after that, it appear that we are still in bootloader (which seems normal as nBOOT0 is still 0 ), this is confirmed by the fact I can connect with CubeProgrammer in Uart mode, thus I am able to change option byte nBoot0=1 and as soon as I apply it, Arduino code executes.
    So it look to me like there is no issue on my side.

According to your description, it looks like system is still in bootloader mode, which explains that arduino code doesn't executes. and when enabling USER_VECT_TAB_ADDRESS, the VTOR register is updated, which could lead to execution of code from flash.

  • Concerning pinMode , I have no issue, all my tests above are made with pinMode and digitalWrite (just take arduino example as is). Maybe on your side, it is a side effect of being in Bootloader mode. So let's fix bootloader issue first.

@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 3, 2022

I finally succeed to flash my STM32G0316-DISCO, so I continue my investigations.
I now have access to BOOT0 pin so like you I disabled nBOOT_SEL, and I used BOOT0 pin.
And here is my finding:

  1. Like you I disabled NRST pin: NRST_MODE=b10 (=2)
  • I set BOOT0 = HIGH
  • I upload Arduino blinky through Uart.
    At the end led doesn't blink as I am still in bootloader
  • I switch BOOT0 = LOW
    led doesn't blink as I am still in bootloader (normal, a Reset is required)
  • Due to NRST disabled, I power OFF/ON
    --> Led is blinking.
  1. Contrary to you I enable NRST pin: NRST_MODE=b11 (=3)
  • I set BOOT0 = HIGH
  • I upload Arduino blinky through Uart.
    At the end led doesn't blink as I am still in bootloader
  • I switch BOOT0 = LOW
    led doesn't blink as I am still in bootloader (normal, a Reset is required)
  • I press the blue button on my Disco which toggles NRST
    --> Led is blinking.

So all seems to work properly

@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

UPDATE: This is the reply to your first response. Will read your second post soon.

Thanks for testing and your long answer.

You are correct, the option byte has to be modified as mentioned in my inital post. To make the USART upload available, the correct boot0 setup must be available.
As mentioned, I have cleared the boot selection bit:
https://github.com/olikraus/stm32g031/blob/e017b221bc534f08e080d7bd3ded5a41824e8bab/enable_boot0/enable_boot0.c#L78
As a consequence, I can use the BOOT0 pin to define whether to jump into bootloader or not.

As you deactivated NRST pin, you could not just act on this pin, so did you power OFF/ON instead ?

yes correct. I think the problem described here is not related to NRST, but I just wanted to describe my complete setup.
So as a conclusion: If I power on the STM32G0, it either executes flash or starts the bootloader depending on the bootloader.

So, this is the normal (expected) Arduino Upload process:

  1. Code is compiled
  2. Code is uploaded to flash memory of the target device
  3. Code is executed

In my case I want to use "USART", so the precondition in my case is: The device must be in bootloader code and wait for USART upload commands.

All in all steps 1 and 2 work without problem. In fact STM32CubeProgrammer nicely uploads via USART.

My expectation is, that Arduino blink.c will get started after upload and the LED should start to blink.
However: This is not the case, the LED doesn't blink.

So what are possible failures could be here?

  1. I have used the wrong pin number in blink.c
  2. The code is uploaded to the wrong memory areay (RAM vs Flash???)
  3. The code is not correctly started by STM32CubeProgrammer
  4. Arduino framework has a bug (startup, delay, pinMode, digitalWrite)

At this point I think that there is an issue with stm32duino.

I started to some further investigation:

  1. Arduino Pin Number for PA13? According to the source code, it could be 6, but I am not sure
  2. I do not know whether STM32CubeProgrammer writes to RAM or Flash, but I assume it is flash only
  3. Correct Startup.

Here I figured out, that avoiding pinMode and digitalWrite AND using -DUSER_VECT_TAB_ADDRESS will start the code on the target device.

So, as a conclusion:
I can compile and upload blink.c. I think I have used the correct pin number, but the blink does not work.

I am really happy you replied to this issue. It would be amazing if I could use stm32duino. Please let me what I can do to support the debugging here.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

I finally succeed to flash my STM32G0316-DISCO, so I continue my investigations.

Nice.

I press the blue button on my Disco which toggles NRST

This means, I always have to execute a manual reset, correct?

The question is, why does cubeprogrammer issue this message? My assumption is, that cubeprogrammer directly starts the just downloaded code without reset (which is very much possible).

RUNNING Program ... 
  Address:      : 0x8000000
Start operation achieved successfully

Moreover, even after power on reset, my code is not executed.

Can you confirm that PA13 is used by pinMode(6, ...)?

@fpistm
Copy link
Member

fpistm commented Feb 3, 2022

In the generic:

With PIN_A5:

So it is correct.
Maybe it could rely on your hardware? It is a custom board? Own PCB? Manually Wired ? Schematics available ?

@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

It had been "Manually Wired".
Let me rebuild the setup from scratch. I will also provide schematics. Again: Thank you both for the support. I will come back with more information.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

I have created a new board with a virgin device:
IMG_20220203_191130166

Soldered on a breakout board:
IMG_20220203_191740427

Final board with schematic:
IMG_20220203_201644104

I have added a normal reset button here.

I can confirm, that this works as described by @ABOSTM (second post):
After upload the automatic start does NOT work. Instead I have switch to normal mode and reset the device.

However, I observe, that the device still freezes if I change something in the code (for example changing the delay time).
In fact it looks like, that the code upload doesn't work any more if the size of the binary changes.

So, at the moment, I have still two issues:

  1. There is no automatic start of the uploaded code (Workaround: Assign GND to BOOT0 Pin and do a manual reset)
  2. Sometimes does not react any more. (Workaround: Full flash erase required)

@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

Ok, here is my problem:
I upload this code:

#define MYPIN 6
// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(MYPIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
  digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(300);      
  digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
  delay(300);      
}

All works fine, the code size is 13416 bytes
If I change the code like this, then it doesn't work any more:

#define MYPIN 6
// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(MYPIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
  digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);
  digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
  delay(200);
}

Code size is now 13412 bytes.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

After some more testing, my result is this:
As soon as the size if the binary code changes, flashing will fail (or at least there is a good chance that flashing will fail).
This can be solved, if the flash memory is fully erased (mass erase). Unfortunately this stm32duino does NOT erase the flash memory.
From what I see at the moment there are two errors in stm32duino

  1. The script stm32CubeProg.sh has a problem:

https://github.com/stm32duino/Arduino_Tools/blob/d0ccf253d7109a4f79e37114f70f8f604c1262d6/stm32CubeProg.sh#L141

${STM32CP_CLI} -c port=${PORT} ${MODE} ${ERASE:+"-e all"} -q -d "${FILEPATH}" ${ADDRESS} "${OPTS}"

Instead it should be ('-' instead of '+'):

${STM32CP_CLI} -c port=${PORT} ${MODE} ${ERASE:-"-e all"} -q -d "${FILEPATH}" ${ADDRESS} "${OPTS}"

Unfortunately, this will still not work, because the mass erase, issued by "-e all" will fail, which leads me to the second problem:

  1. Cube Programmer fails with mass erase "-e all" for the STMG031J6

The STM32G031J6 only has 32KB Flash ROM, however the Cube Programmer reports:

Chip ID: 0x466 
BootLoader protocol version: 3.1
Device name : STM32G03x/STM32G04x
Flash size  : 64 KBytes (default)
Device type : MCU
Revision ID : --  
Device CPU  : Cortex-M0+


Mass erase ... 

Error: Mass erase operation failed.

I assume that the cube programmer tries to erase 64KB which will fail, because only 32KB are available.

At this point we could modify this line:
https://github.com/stm32duino/Arduino_Tools/blob/d0ccf253d7109a4f79e37114f70f8f604c1262d6/stm32CubeProg.sh#L6
to
ERASE="-e [0 15]"

But this will not make much sense, for other controllers. Applying a much bigger range to cover all STM controllers
ERASE="-e [0 255]"
will work, but will also generate several errors.

@olikraus olikraus changed the title Generic Board STM32G031J6, issues with starting the downloaded code (pinMode hangs) Generic Board STM32G031J6, issues with starting the downloaded code (pinMode hangs) [Linux] Feb 3, 2022
@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

I assume the problem is related to Linux only, because my problem was caused by an .sh script, which probably exists only on Linux machines.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

Ah, I was probably wrong with the Linux assumption. stm32CubeProg.sh will be executed via busybox also on windows, so I assume, that the same problem will appear also on windows machines.

@olikraus olikraus changed the title Generic Board STM32G031J6, issues with starting the downloaded code (pinMode hangs) [Linux] Generic Board STM32G031J6, issues with starting the downloaded code (pinMode hangs) Feb 3, 2022
@olikraus
Copy link
Contributor Author

olikraus commented Feb 3, 2022

I have created another issue for STM32CubeProgrammer, see stm32duino/Arduino_Tools#82

I think, this issue can be closed. Thanks a lot for your amazing support and providing STM32duino to the Arduino community.

@fpistm
Copy link
Member

fpistm commented Feb 4, 2022

Hi @olikraus
there is no issue with the script.

First by defaut the full erase is not request. It is a option added for some user which use the boards.local.txt or the platform.local.txt feature.

About the

1. The script stm32CubeProg.sh has a problem:

https://github.com/stm32duino/Arduino_Tools/blob/d0ccf253d7109a4f79e37114f70f8f604c1262d6/stm32CubeProg.sh#L141

${STM32CP_CLI} -c port=${PORT} ${MODE} ${ERASE:+"-e all"} -q -d "${FILEPATH}" ${ADDRESS} "${OPTS}"

Instead it should be ('-' instead of '+'):

${STM32CP_CLI} -c port=${PORT} ${MODE} ${ERASE:-"-e all"} -q -d "${FILEPATH}" ${ADDRESS} "${OPTS}"

Unfortunately, this will still not work, because the mass erase, issued by "-e all" will fail, which leads me to the second problem:

${ERASE:+"-e all"} is the correct syntax in bash (See after). If ERASE is empty then null string else "-e all". Like the default protocol version is "1" and not "11" then erase all is not set.
image

@olikraus
Copy link
Contributor Author

olikraus commented Feb 4, 2022

ok, I understand.

Anyhow, the problem is: If my code for STM32G031J6 changes in size, then the execution fails and requires a full (or at least suffient) erase, which does not happen at the moment.

The best solution would be, if I could enable full Flash erase (mass erase) operation for the STM32G031J6. Is there an option in the GUI already available for this? I think this applies to all STM32G031J6: Any upload will require a mass erase.

@fpistm
Copy link
Member

fpistm commented Feb 4, 2022

I don't think mass erase is required.
There is no option in the GUI to enable the mass erase.
set the protocol version to 11 instead of one will enable the full erase:

GenG0.menu.upload_method.serialMethod.upload.protocol=1

as stated you can use the platform.local.txt to customize your setup or use this https://github.com/stm32duino/wiki/wiki/Custom-board-based-on-a-core

@olikraus
Copy link
Contributor Author

olikraus commented Feb 4, 2022

set the protocol version to 11 instead of one will enable the full erase:

Thanks for the hint, I will try this.

I don't think mass erase is required.

As mentioned above, the newly uploaded code to STM32G0 fails if the binary size was changed.
It is not neccesarily the mass erase, but there should be some good erease which allows reliable usage of STM32duino.
At least from myperspective my STM32G0 boards are not usable via STM32duino.
However, if a mass erase is executed before upload, then it seems to work without issues.

@fpistm
Copy link
Member

fpistm commented Feb 4, 2022

I've made the same setup than you and here the result:

      -------------------------------------------------------------------
                       STM32CubeProgrammer v2.9.0                  
      -------------------------------------------------------------------

Serial Port COM10 is successfully opened.
Port configuration: parity = even, baudrate = 115200, data-bit = 8,
                     stop-bit = 1.0, flow-control = off

Timeout error occured while waiting for acknowledgement.
Activating device: OK
Board       : --
Chip ID: 0x466 
BootLoader protocol version: 3.1
Device name : STM32G03x/STM32G04x
Flash size  : 64 KBytes (default)
Device type : MCU
Revision ID : --  
Device CPU  : Cortex-M0+


Mass erase ... 

Error: Mass erase operation failed.
Please verify flash protection


Memory Programming ...
Opening and parsing file: Blink.ino.bin
  File          : Blink.ino.bin
  Size          : 13720 Bytes
  Address       : 0x08000000 


Erasing memory corresponding to segment 0:
Erasing internal memory sectors [0 6]
Download in Progress:


File download complete
Time elapsed during download operation: 00:00:01.837

RUNNING Program ... 
  Address:      : 0x8000000
Start operation achieved successfully

Even if the mass erase failed, during the next step (programming) it first erases the 0-6 sectors and flash without any issue.
I've made several tests and sometimes it starts properly sometime not but in this case if reset the board then the program start properly.
About the binary size I don't think it is the issue in any case your binary is less than 14kb --> 7 sectors of 2kb indicated as [0-6] in the erase steps.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 4, 2022

if reset the board then the program start properly.

This is exactly not the case. I change the size only by 4 bytes, then the flashed software becomes anusable. Also any reset does not help here. Let me repeat my problem:

  1. Switch into Bootloader Mode (BOOT0 Pin=high)
  2. Press reset to enter Bootloader USART Sync wait
  3. Full erase of flash memory (using an external tool stm32flash from sf.net)
  4. Press reset to again enter Bootloader USART Sync wait
  5. Upload the following code via Arduino IDE (USART, as discussed above)
#define MYPIN 6
// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(MYPIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
  digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);
  digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
  delay(200);
}
  1. Change Boot0 pin to low
  2. Press reset: Blick starts as expected
  3. Change Boot0 pin to high
  4. Press reset: Blink stops, Bootloader enters USART sync
  5. I modify the delay from 200 to 300 (this will cause more bytes to be occupied, flash size becomes bigger)
#define MYPIN 6
// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(MYPIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
  digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(300);
  digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
  delay(300);
}
  1. Upload of this code via Arduino IDE
  2. Change Boot0 pin to low
  3. Press reset: Nothing happens... and this is my problem

Erasing internal memory sectors [0 6]

I see the same message in both cases in the Arduino IDE, but still it doesen work.

14kb --> 7 sectors of 2kb indicated as [0-6]

I also assumed that one page is 2kb. However there is another miracle.
If I call the cube programmer CLI with "-e [0 31]" then the expectation would be that I get an error, because 32*2kb = 64kb, but the G031J6 only has 32 KB. However, "-e [0 31]" will NOT generate an error.
In fact "-e [0 33]" will generate an error only for sector 32 and 33. It looks like that cube programmer assumes 1kb as one page only.

However, if cube programmer assumes one page to be 1kb, then

Erasing internal memory sectors [0 6]

would only erase 7kb (out of the required 14 kb). Maybe cube programmer has a real problem, because it erases only half of the code. This would indeed explain why any code change will not work.

Maybe you can confirm the malfunction for the above 13 steps...

EDIT: Changed the delay values in the code

@fpistm
Copy link
Member

fpistm commented Feb 4, 2022

I've succeed to reproduce your issue sometimes after the reset, this is not regular and the board is in unknown step as event the STLink could not connect anymore.
I guess we had issues with CubeProgrammer and BL.
Anyway, with the same delay (200) I can have it working or not same with 1000.
If you flash the binary with the STLink it will works properly.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 4, 2022

I've succeed to reproduce your issue

I am happy to read this.

If you flash the binary with the STLink it will works properly.

I have not checked this, but if I do a full erase, then it will also work again.

Ok, I understand that I could use STLink.
However, let's assume I want to continue with USART upload:
Do you see any chance to solve this within Arduino IDE?

From my perspective, if STM32duino would add "-e [0 31]" to the cube programmer cli as part of the upload arguments for the STM32G031J6, then the problem would be solved.

(again, as discussed, "-e all" does not work and also the GenG0.menu.upload_method.serialMethod.upload.protocol=11 trick will probably not work, because it just enables the none working "-e all")

@fpistm
Copy link
Member

fpistm commented Feb 4, 2022

From my perspective, if STM32duino would add "-e [0 31]" to the cube programmer cli as part of the upload arguments for the STM32G031J6, then the problem would be solved.

Probably but it is just a workaround. You can use it using the platform.local.txt or the custom core as show in the wiki.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 4, 2022

Probably but it is just a workaround. You can use it using the platform.local.txt or the custom core as show in the wiki.

Sure, but i am also interessted in a more generic solution. The above problem will happen to everyone who uses STM32duino with the STM32G031J6, right? So it would be great if STM32duino could solve this problem somehow in the STM32duino project.

@fpistm
Copy link
Member

fpistm commented Feb 4, 2022

Probably. But I can't be sure as it could depend of the bootloader version available within the mcu.
It could be also an issue with the STM32CubeProgrammer in that case a later version could solve the issue.

Changing the core to add "-e [0 31]" will impact all the generic G0 variants but it is probably not correct for all.

While I have not the exact reason why it fails, I would not deploy a fix as it could implies a lot of change in the core.
Please be patient 😉

@olikraus
Copy link
Contributor Author

olikraus commented Feb 4, 2022

Changing the core to add "-e [0 31]" will impact all the generic G0 variants but it is probably not correct for all.

Very much correct. I also didn't meant this as a generic solution. I think a generic solution should allow individual upload arguments for cube programmer cli based on the selected controller, so that J6 gets -e [0 31] and J4 might require -e [0 15].

While I have not the exact reason why it fails, I would not deploy a fix as it could implies a lot of change in the core.
Please be patient 😉

I am happy that you already guided me to find a workaround for my issue. At least I now know how to modify STM32duino so that it works with my board. Thats already a great success. Again: THANKS A LOT!

@fpistm
Copy link
Member

fpistm commented Feb 4, 2022

Changing the core to add "-e [0 31]" will impact all the generic G0 variants but it is probably not correct for all.

Very much correct. I also didn't meant this as a generic solution. I think a generic solution should allow individual upload arguments for cube programmer cli based on the selected controller, so that J6 gets -e [0 31] and J4 might require -e [0 15].

Unfortunately, Arduino boards definition is very limited. So hard to do that or it would required to define all the boards at the same level with all the submenu duplicated 😉 This will lead to a boards.txt more than 100x longer and a very long menu ...

@olikraus
Copy link
Contributor Author

olikraus commented Feb 4, 2022

hmm.. I understand. So, it would be great if -e all would work....

@olikraus
Copy link
Contributor Author

olikraus commented Feb 5, 2022

I tried to figure out whether CubeProgrammer works with 1kb or 2kb sector size. So I did the following test:

  1. Clear the flash

  2. Write 4000 bytes with value 4 to flash

  3. Execute -e [0 1] --> this should clear 4096 bytes if sectors are 2Kb

  4. Check whether all flash is cleared

  5. Clear and verify flash

./STM32_Programmer.sh -c port=/dev/ttyUSB0 -e [0 31]

./STM32_Programmer.sh -c port=/dev/ttyUSB0 -blankcheck
Flash memory blank checking...
Flash memory is empty.
  1. Write 4000x byte 4 to the flash
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -fillmemory size=4000 pattern=4

The used start address is 0x08000000.
The used filling data size is 8 bits.
Filling memory operation:
  Start address           : 0x08000000
  Size(Bytes)             : 0x00000FA0
  Data value              : 0x00000004
  Filling data size(Bytes): 8 bits


Erasing internal memory sectors [0 1]

The filling memory operation achieved successfully

./STM32_Programmer.sh -c port=/dev/ttyUSB0 -blankcheck


Flash memory blank checking...

Warning: Flash memory is not empty at 0x08000000.

The warning is correct, the first none-empty byte is at 0x08000000

  1. Erase [0 1]
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -e [0 1]
  1. Check the result
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -blankcheck


Flash memory blank checking...

Warning: Flash memory is not empty at 0x08000800.

As a conclusion the "-e [0 1]" will only clear memory from 0 to 2047. This means the "-e" command expects sectors as 1kb size and indeed "-e [0 31]" is required to erase the complete flash of the STM32G031J6

During pattern flashing the output of cube programmer had been:

Erasing internal memory sectors [0 1]

This would make sense, if the erase sector size is 2kb. So at least, the input arguments to the -e command are different (1kb) to the generated output (2kb).

@olikraus
Copy link
Contributor Author

olikraus commented Feb 5, 2022

I did another test:

  1. Write 4000 bytes with value 0x0f to 0x08000000
  2. Write 4000 bytes with value 0x55 to 0x08000000

Expectation would be, that I see 4000 bytes with value 0x55 0x08000000.
I will use the -fillmemory command of cube programmer for this, so here are the results:

  1. Initial clear of the memory to get a known state
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -e [0 31]


./STM32_Programmer.sh -c port=/dev/ttyUSB0 -blankcheck

Flash memory is empty.
  1. Write the 0x0f pattern
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -fillmemory size=4000 pattern=0x0f

The used start address is 0x08000000.
The used filling data size is 8 bits.
Filling memory operation:
  Start address           : 0x08000000
  Size(Bytes)             : 0x00000FA0
  Data value              : 0x0000000F
  Filling data size(Bytes): 8 bits


Erasing internal memory sectors [0 1]

The filling memory operation achieved successfully
  1. Read out 6000 bytes and show the content with "od" as hex data
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -r 0x08000000 6000 tmp.bin && od -A x -t x1 tmp.bin


000000 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f
*
000fa0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
*
001770

This looks very good, all is ok

  1. Write the 0x55 pattern
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -fillmemory size=4000 pattern=0x55

The used start address is 0x08000000.
The used filling data size is 8 bits.
Filling memory operation:
  Start address           : 0x08000000
  Size(Bytes)             : 0x00000FA0
  Data value              : 0x00000055
  Filling data size(Bytes): 8 bits

Erasing internal memory sectors [0 1]

The filling memory operation achieved successfully
  1. Check whether the 0x55 has overwritten the 0x0f
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -r 0x08000000 6000 tmp.bin && od -A x -t x1 tmp.bin

000000 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
*
000800 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f
*
000fa0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
*
001770

This is wrong. Only 2048 of the 4000 bytes with 0x055 had been written to the flash. Still we can see 0x0f values although we tried to overwrite these values.

Cube programmer is broken and does not work as expected for the fillmemory command.

I think the same wrong behavior applies to flash write command at least for the STM32G031J6.
STM32duino can not be used out of the box of the STM32G031J6 with USART interface.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 5, 2022

I executed the fillmemory test also with a STM32G031F8 device (64KB flash, USART interface) with the same wrong result.
Also "-e all" does not work
IMG_20220205_102831204_HDR

So, STM32G031F8 and STM32G031J6 are affected (unfortunately I do not have other STM32Gxxx devices for testing)

@olikraus
Copy link
Contributor Author

olikraus commented Feb 5, 2022

I have tested the behavior with STM32G031F8 and SWD interface. Please excuse using a cheap stlink clone, but as a hobbyist, my budged doesn't allow me to buy expensive equipment.

Results are good with SWD interface: "-e all" works as expected and also the the fillpattern command works as expected. Overwriting the 0x0f pattern with 0x55 correctly reports:

      -------------------------------------------------------------------
                        STM32CubeProgrammer v2.9.0                  
      -------------------------------------------------------------------

ST-LINK SN  : 220A030232124153354B4E00
ST-LINK FW  : V2J29S7
Board       : --
Voltage     : 3,16V
SWD freq    : 4000 KHz
Connect mode: Normal
Reset mode  : Software reset
Device ID   : 0x466
Revision ID : Rev 1.1
Device name : STM32G03x/STM32G04x
Flash size  : 64 KBytes
Device type : MCU
Device CPU  : Cortex-M0+
BL Version  : --


UPLOADING ...
  File          : tmp.bin
  Size          : 6000 Bytes
  Address:      : 0x8000000
Read progress:
[==================================================] 100% 
Data read successfully
Warning: The file tmp.bin already exists, it will be overwritten
Time elapsed during read operation is: 00:00:00.040
000000 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
*
000fa0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
*
001770

So it looks like Cube Programmer 2.9.0 has a problem with all STM32Gxxx devices connected via USART only (SWD works correctly).

IMG_20220205_104342092

@olikraus
Copy link
Contributor Author

olikraus commented Feb 5, 2022

More remarks: The STM32G031Fx is not listed in STM32duino, probably I could use STM32G031Kx instead, but then the pin numbers might be different. Anyhow, just an observation.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 5, 2022

I tried to figure out how to change STM32duino so that the erase operation works correctly.
Unfortunately "-e all" just aborts with error and does not erase anything.
As a consequence your suggestion

set the protocol version to 11 instead of one will enable the full erase:

Does not work, because the "-e all" will not work at all for this device. So the only option to make the STMG032xx work correctly via USART flash is to modify stm32CubeProg.sh.

Summary

  • CubeProgrammer does not flash correctly via USART for several STM32G0xx (probably for all devices)
  • CubeProgrammer fails with error for the STM32G031J for "-e all"
  • There is (probably) no workaround in STM32duino to fix this via boards.txt or platform.txt. Instead modifing stm32CubeProg.sh seems to be the only option.

@fpistm
Copy link
Member

fpistm commented Feb 7, 2022

More remarks: The STM32G031Fx is not listed in STM32duino, probably I could use STM32G031Kx instead, but then the pin numbers might be different. Anyhow, just an observation.

You can add the generic quickly following the wiki to add a new board.

@fpistm
Copy link
Member

fpistm commented Feb 7, 2022

For the flash, based on the Ref Man, 2k page size is correct:
image

image

We will check with STM32CubeProgrammer about this issue and I agree that a fix could only be done in the script. I've already think about that but waiting some internal feedback.

@olikraus
Copy link
Contributor Author

olikraus commented Feb 7, 2022

We will check with STM32CubeProgrammer about this issue and I agree that a fix could only be done in the script. I've already think about that but waiting some internal feedback.

Thanks!

@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 7, 2022

Internal Ticket 122350

@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 10, 2022

@olikraus,
I found 2 issues that prevent proper execution of application after UART Bootloader.
I proposed a fix: #1653
It works for me, (no need for a full erase)

@olikraus
Copy link
Contributor Author

I am a little bit confused regarding closing this topic: #1653 will solve the automatic startup after download (USER_VECT_TAB_ADDRESS and clock setup topics).
However the CubeProgrammer is broken from my perspective and will not allow a proper upload via USART of the code length has changed.

I mean this issue has described two issues and only one is now solved by #1653

How shell we deal with the USART flash problems? Any progress on your Internal Ticket 122350?

@ABOSTM
Copy link
Contributor

ABOSTM commented Feb 14, 2022

From my point of view, yes, this issue is closed:
Everything works on my side thanks to both fixes.
The internal Ticket 122350 concerns Mass erase. Despite issue is still there (it is not closed internally),
Mass erase is not needed once both fixes are present. (So in the context of Arduino this is closed)

The issue that upload via UART is broken when code length changes, is I think invalid (or miss interpretation). I have not seen evidences that links code length change and bootloader issue. And this is not something I observed during my analysis.
And finally once I have both fixes integrated, I face no issue.
I presume this was a side effect of both issues I fixed.

Now if you still have some issues using UART bootlader despites the fixes I made, then I propose to open a new issue, and in any case, experiments should be restarted from scratch with both fixes.

@olikraus
Copy link
Contributor Author

Now if you still have some issues using UART bootlader despites the fixes I made, then I propose to open a new issue, and in any case, experiments should be restarted from scratch with both fixes.

I agree, this makes sense.

@olikraus
Copy link
Contributor Author

The problem mentioned on 3 Feb seems to be resolved now with CubeProgrammer 2.10

Thanks to all!

@CSV-12
Copy link

CSV-12 commented Aug 28, 2022

@olikraus Looks like you solved the problem, but I'm wondering about that resistor value in series with the LED. Typically these are 1.7V and power supply is at 3.3V so the 100 Ohm resistor will drop 1.6V pulling the max current of 16mA from the MCU pin.
Maybe not a happy value?

table19

@olikraus
Copy link
Contributor Author

In fact the resistor is not required. The MCU will limit the current to the specified value from the datasheet: you can connect a LED directly to any of the pins.

@CSV-12
Copy link

CSV-12 commented Aug 30, 2022

Great!

I see a "20mA" condition in Table 53, but nothing about current limiting. Table 19 above is from paragraph 5.2, "Absolute maximum ratings".

An active current limiting would involve more on-die parts that would measure current and turn off at a threshold value, allowing short to ground and to VCC which is also mentioned in the data sheet.

Where did you find "_The MCU will limit the current to the specified value from the datashee_t" ??

@olikraus
Copy link
Contributor Author

The current limitation is an effect/ characteristics of the underlaying CMOS technology. It doesn't require any extra parts. Unlike TTL logic a CMOS transistor has still a significant resistance if the transistor is fully turned on (So called on-resistance of the MOS transistor). This "build in" resistance will always limit the output current.

@CSV-12
Copy link

CSV-12 commented Aug 31, 2022

Apply Ohm's Law to that FET's RDS-on and you will soon exceed what a MCU port can handle. 0.020mA*3.3V=0.066W.
Some LEDs will increase its contact potential enough as as current goes up, and possibly reach an tolerable equilibrium, in the best cases. Overloading a IO pin can in worst cases lead to erratic behavior. Shorting a port pin to ground will quickly lead to a failure. Not worth the risk.
Your assertion is not based on facts.

@olikraus
Copy link
Contributor Author

olikraus commented Aug 31, 2022

Apply Ohm's Law to that FET's RDS-on and you will soon exceed what a MCU port can handle. 0.020mA*3.3V=0.066W.

Each FET has a kind of a lowest RDS-on. This will limit the current. Of course the FET may still get destroyed if RDS on is very low and no proper cooling is applied. And yes: for an MCU you can not expect all GPIOs to deliver 20mA: There is an upper limit of what the overall MCU can deliver (this is also mentioned in the MCU datasheet).

Moreover your calculation is wrong, because you need to multiple the current with the voltage over the enabled output FET of the driver stage of the GPIO of the uC. This, however, is the applied power voltage minus the forward voltage of your LED: 0.020mA * (3.3V-1.8V)

Your assertion is not based on facts.

Just to clarify this. I was talking about a single GPIO pin.

Regarding facts, you could look at this FET: https://eu.mouser.com/datasheet/2/196/Infineon_BSS127I_DataSheet_v02_01_EN-2237807.pdf
It can only deliver 21mA (comparable to a typical uC output) and diagrams 5 and 6 clearly show, that the output current is limited.
According to diagramm 6, RDS-on is at least 280 Ohm (estimated from the diagramm).
If we assume Vds as 3.3V and a forward voltage of your 20mA LED of 1.8V, then we have: (3.3V-1.8V)/280Ohm = 5.3mA
So you can add your LED without problem and without additional resistor. In fact LED will not be at max brightness, because 5.3mA is still much lower than 20mA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants