SOLVED: STM32F103C won’t retain program, is it loading into RAM

grassm
Mon Mar 27, 2017 1:41 am
Not sure if this was the best forum for my question; maybe “libraries and hardware” would have been better?
(Blue Pill, IDE 1.8.0, Windows 7 OS) I couldn’t find anything in the FAQs or forum that seem to address this. This is how it started…
I was putting the final touches on my code. Once downloaded I disconnect the Serial to ttl and connect the board to the high current driver board, change the two program shunts/straps/shorts so that Boot0 and Boot1 are low. The code would normally run when it’s powered up. The it stopped retaining the code. So I used a different computer and the code was retained and all worked well. After about 3 more compile and download cycles, it started doing the same thing. Once the power is removed, shunt set Boot0 to low, the stm32 was dead. I’m guessing that the code is being loaded into RAM and then run from there. But, I never changed anything in my IDE; all I changed was code in my program.
I remember that some where in my STM32 travels, I read something about the Boot1 being High(logical 1) would load the code into and then run from RAM. Couldn’t find that in my notebook though. I have tried 4 other Blue Pills (bought at different times), but they don’t retain the code. Which kind of rules out the Boot1 position. All of the Blue Pills had worked correctly before.
I tried vers 1.8.2 and then it wouldn’t even compile, but that was me. I hadn’t run the board manager to load the STM32 boards. (Roger Clark….Just so you know, some of us do read the FAQs. ;) ) Anyone have any idea what happened? Not sure if it’s related, but my setup was using the “portable” 1.8.0. IDE. I had the IDE and the folder for my programs in my “Drop Box”, which allowed me to work on any of my 3 computers. I’ve since tried all 4 computers in the house, all Win 7 home premium 64bit. The uCs just don’t retain the code. ??

grassm
Mon Mar 27, 2017 1:48 am
I’ll have to see if attaching a battery to VBat will retain the code. Not the best solution, but it might get me through till I can solve the problem. Saw something about that in “Re: Guide: “I’m new here – which board should I buy?”

grassm
Mon Mar 27, 2017 3:27 am
I haven’t FIXED the problem yet, but I have a work around……I found enough info to hook up my st-link v2. I can download my code via st-link and it retains the code. However….I’m not sure how to get the output from Serial.print. Even using the USB to serial module that shows up (on my system as COM59) nothing shows up on the monitor. I’ll have to think/search some more. The st-link seems to work well enough. Now just need to figure out how to use it to it’s fullest for debugging.

stevestrong
Mon Mar 27, 2017 8:29 am
The serial map depends on the upload method as following:

[*] bootloader & st-link:
Serial = USBSerial
Serial1 = USART1
Serial2 = USART2
Serial3 = USART3
[*] serial:
Serial = USART1
Serial1 = USART2
Serial2 = USART3

See http://www.stm32duino.com/viewtopic.php … 462#p25373.


edogaldo
Mon Mar 27, 2017 8:47 am
Another tip: even if you upload with Serial, the stm32duino framework assumes you have the bootloader installed, in fact it compiles for and uploads the sketch to address 0x08002000.
If you don’t have the bootloader installed then on the next restart the MCU won’t find anything at 0x08000000 and thus won’t start your sketch..

Sorry, I double checked and with Serial upload method the code is compiled for address at 0x08000000 so, please ignore what I wrote..


grassm
Mon Mar 27, 2017 3:13 pm
@edogaldo Thanks for taking the time to reply. For me the code compiles for 0x08000000 for both serial and st-link.
Changing Serial. to Serial1. took care of the monitor. It’s a small pain to have to switch between COM1(st-link) and COM59(Serial monitor), but it works. Thanks for the help!
Because it’s convenient to use the 4 pin header at the end of the blue pill, I’ll probably use the st-link for programming. I’ll have to do some searching to see what I can do with the st-link as far as debugging. It’s been a long time since I’ve used an ICE. Since I started using Arduino I haven’t had anything for debugging except the serial monitor.
Because I may end up using both the “USB to serial” and the “ST-LINK” for programming, I’m going to set up my code as
#define SERIAL Serial1. // or Serial.
Serial.print would become SERIAL.print which would become Serial.print or Serial1.print based on the #define statement. That way I can change the code by changing the #define SERIAL to Serial. or Serial1. Or is there a better way to do that?

grassm
Mon Mar 27, 2017 3:19 pm
I’m using the bootloader that came on the Blue Pill. Would the STM32duino-bootloader from https://github.com/rogerclarkmelbourne/ … bootloader correct the problem I was having when downloading code via the USB to serial?

grassm
Mon Mar 27, 2017 4:11 pm
Well, after playing around with the #define PRINT_INFO
#define SERIAL Serial //or Serial1 if using the st-link

grassm
Tue Mar 28, 2017 1:32 am
Well it’s back to what it was doing before. It uploads to the RAM and goes away after cycling power or pressing the reset. Same thing using ST-link or USB to Serial TTL. I’M READY TO SCREAM!

grassm
Tue Mar 28, 2017 2:16 am
Configured for ST-LINK upload. ST-LINK on COM1
This is the code that I used to test for the PWM pins. Below the code is the output from the compile.
I’ve wasted well over 30 hours on this. I’m ready to throw all STM32 in the trash.
I don’t see anything that’s a red flag!

#define MAX_LEVEL 65535
//+++++++++++++++++++++++++++++++++++++++++++++++++setup++++++++++++++++++++++++++++++
void setup() {
for(int i=0;i<=31;i++)
{
pinMode(i,PWM);
pwmWrite(i,0);
}
}//------------------end of setup--------------
//+++++++++++++++++++++++++++++++++++++++++++++++ main loop() +++++++++++++++++++++++++++++
void loop() {
for(int index=0;index<=31;index++)
{
for(int level=0;level<=MAX_LEVEL;level += 50)
{
pwmWrite(index, level);
delay(1);
}//end of increase level
for(int level = MAX_LEVEL; level >= 0;level -= 50)
{
pwmWrite(index, level);
delay(1);
}//end of decrease level
pwmWrite(index, 0);
}//end of index loop
}//------------------------------------end of main loop ----------------------------------------------


stevestrong
Tue Mar 28, 2017 8:54 am
grassm wrote:
//+++++++++++++++++++++++++++++++++++++++++++++++++setup++++++++++++++++++++++++++++++
void setup() {
for(int i=0;i<=31;i++)
{
pinMode(i,PWM);
pwmWrite(i,0);
}
}//------------------end of setup--------------

grassm
Tue Mar 28, 2017 4:46 pm
Hey Steve,
Then how do you sequentially step through pins?

edogaldo
Tue Mar 28, 2017 4:52 pm
grassm wrote:Hey Steve,
Then how do you sequentially step through pins?

grassm
Tue Mar 28, 2017 6:08 pm
Hi Steve,
I don’t remember ever seeing anything about that array. That doesn’t mean I never saw it; I just don’t remember it. At 66yr, I forget faster than I can learn.

I’ve changed my code and made some progress. The way I was addressing/configuring the pins was causing the problems.
It seems that I can address the pins by the integer name in digital mode and everything is fine, but doesn’t like it when doing the PWM.

I have some testing to do and if it all comes together, I’ll post what I find.
Thanks again. I may really owe you! :oops:


grassm
Tue Mar 28, 2017 9:52 pm
@edogaldo AND stevestrong Didn’t realize that both of you helped with that pin name calling. Thanks to both of you.
Once I have this completely tested I’ll mark this as solved and put in the results. :D

grassm
Wed Mar 29, 2017 4:07 am
Much thanks to edogaldo and stevestrong for their help.
RESOLVED:
I was addressing the pins using an array that contained the pin number in the order that I wanted them in. I would pwmWrite(1, value).
// A8, A11, B1, B0, A7, A6, A3, A2, A1, A0, B6, B7
int ledPin[] = { 8, 11, 17, 16, 7, 6, 3, 2, 1, 0, 22, 23 }; //organize all PWM pins best layout order.

grassm
Fri Mar 31, 2017 2:56 am
Well, maybe I spoke too soon. I had been using the analogWrite(boardPWMPins[index],value). When I changed to the pwmWrite(boardPWMPins[index],value);, the code would skip the first and last pin of the board.ccp declared array. After some head scratching, backing up to the last know GOOD code version, and changing small parts at a time, it turns out that if I use the analogWrite(boardPWMPins[index],value) once then it no longer skips the 1st and last pin of the array. When I say skip, I mean that the uC processes the statement, but the pin/LED connected to it doesn’t respond. I’ve tested it several times. My st-link stopped working :evil: so I’m back to using USB to Serial TTL. Using the serial monitor (which messes up the A9 and A10 pins), I printed out the index number into the boardPWMPin[] and the value from the array. Those print outs were always correct and always the same.
So, I’m not sure what’s going on but it seems to be a bug. May be my code. The program (hate the word sketch) has the main tab (with the main loop and setup) along with 12 other tabs for different sequences. I do not use a .c or anything so it becomes a .ino.
For background: It’s been a long time since I programmed in Turbo C(1996) and I haven’t been able to get the .c or .ccp file extensions to work. I’ve had programming training but this was Gould Sel in 1988. I’ve also had Pascal. Never got the hang of OOP and hated Ada. Most of the rest of my programming has been in Asm86. If some one wants to look at my code I can zip the directory and send it. Or , I could cut and paste all of it into the code brackets.
I went with the stm32 because I needed more PWM pins than the Nano or mini provide.
The program is for a large light bar for a parade float. So it’s not critical. Only the Knight Rider sequence needed the PWM for the trailing LEDs.

stevestrong
Fri Mar 31, 2017 7:20 am
You could post the code on github, so that it is recorded for the infinity 8-)
We can then have a look on it.

edogaldo
Fri Mar 31, 2017 10:50 am
grassm wrote:Well, maybe I spoke too soon. I had been using the analogWrite(boardPWMPins[index],value). When I changed to the pwmWrite(boardPWMPins[index],value); […]

grassm
Sat Apr 01, 2017 12:26 am
@ edogaldo Yes, I am aware of those 2 differences. I’ll still play around with it; I don’t like not understanding what’s going on. That’s why I like assembly so much; I can control almost everything! I did initialize the pins before I used the pwmWrite( ,) statements. If I don’t use the analogWrite(,) statement on all pins at least once, some of them don’t operate the way they should when I use the pwmWrite(). Like I said I’m not finished peeking and poking. I do have a Segger J-link but haven’t been able to get anywhere with it. Now I really have a need for that.

@stevestrong: I’ve never posted on Github, but I’ll give it a look. It’s not like anyone’s going to make any money from this code. Let me look through the code a couple more times and then I’ll see what I have to do to post it.

Thanks again to both of you for your help. Nothing worse than being alone in the world with a problem.
Cheers!


grassm
Sat Apr 01, 2017 3:14 am
OK Steve, I think that I have it set up correctly on Github. https://github.com/grassm/LED-Light-bar-sequencer
First time through so I may have done something wrong; let me know. Video of it working too.
Thanks again!

zmemw16
Sat Apr 01, 2017 3:22 am
i hope you had eye protection on :D

grassm
Sat Apr 01, 2017 3:34 am
zmemw16 I don’t look directly at it! :)

zmemw16
Sat Apr 01, 2017 3:41 am
it was bad enough for the camera, had me blinking and some dots as well
:D

edogaldo
Sat Apr 01, 2017 6:20 am
grassm wrote:OK Steve, I think that I have it set up correctly on Github. https://github.com/grassm/LED-Light-bar-sequencer
First time through so I may have done something wrong; let me know. Video of it working too.
Thanks again!

stevestrong
Sat Apr 01, 2017 9:26 am
A correct pin initialization sequence should look like this (as edogaldo also mentioned):
for (index =FIRST_LED; index<= LAST_LED; index++)
{
pinMode(boardPWMPins[index], PWM );
pwmWrite(boardPWMPins[index],0);
}

grassm
Sat Apr 01, 2017 2:12 pm
edoldago and stevestrong:
I’m always amazed how I can look at something at least 100 times and not see IT!
I went back to when I was converting from the analogWrite to pwmWrite and it was there all along.for (inDex =FIRST_LED; inDex<= LAST_LED; inDex++)
{
pinMode(inDex, PWM );
pwmWrite(boardPWMPins[inDex],0);
#ifdef PRINT_INFO
SERIAL.println( boardPWMPins[inDex] );
#endif
}

grassm
Sat Apr 01, 2017 2:25 pm
Steve,
I’m still confused by your comment:
stevestrong wrote:
Nevertheless, the array indexing is still dangerous because LAST_LED can be (by chance) higher than sizeof(boardPWMPins[]).

How would you have coded the loop for the index var? I’m not arguing with you; I seriously want to learn! I know all to well, I am not the sharpest too in the shed! What is the best way to do this pin initialization?
…and not sure about the correct way to use the forum “quote.” I had to manually put the test into the quote but it ends up within the actual quote. Yours shows up on the line with the large quotation mark.


stevestrong
Sat Apr 01, 2017 2:34 pm
– How to quote? Press the quotation sign of the post you want to quote (top right).
Or type in:

[quote="stevestrong"] bla bla [/quote]


grassm
Sat Apr 01, 2017 3:01 pm
Ahhhhhh! The old sizeof. Evidently not something that I use enough. :oops: and makes perfect sense. In my mind (where I’m quite often wrong) my thought was “someone else’s code can’t know how many LEDs or elements in MY array. And, if THEY change THEIR code making it smaller than what I need, it will break my code. Well, it will break my code either way. So, YES, I see your point and agree. Sizeof() is the way to do it.
Now, if I only needed 10 of the 12 pins, would it be better to code it as for (index=0; index<=sizeof(boardPWMPins[])/sizeof(uint8_t)); index++)
{
if( index > sizeof(boardPWMPins[]) Serial.println( "index exceeds array size")
else
{
pinMode(boardPWMPins[index], PWM );
pwmWrite(boardPWMPins[index],0);
}
}

stevestrong
Sat Apr 01, 2017 8:40 pm
If you condition index to be always less than sizeof array, then the next if should check for the last_led, i think.

Leave a Reply

Your email address will not be published. Required fields are marked *