First pass at a BluePill Variant

Rick Kimball
Sat Sep 17, 2016 1:00 am
https://github.com/RickKimball/Arduino_Core_STM32F1

This needs much more work. What is working. You can blink an led and the clock is using the XTAL and runs @ 72MHz

BlinkWitoutDelay HAL style for a BluePill:
/* Blink without Delay

Turns on and off a light emitting diode (LED) connected to a digital
pin, without using the delay() function. This means that other code
can run at the same time without being interrupted by the LED code.

The circuit:
* LED attached from pin 13 to ground.
* Note: on most Arduinos, there is already an LED on the board
that's attached to pin 13, so no hardware is needed for this example.

created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
modified 11 Nov 2013
by Scott Fitzgerald

This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number :
const int ledPin = PC13; // the number of the LED pin

// Variables will change :
int ledState = LOW; // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated

// constants won't change
unsigned long interval = 100; // interval at which to blink (milliseconds)
const long i_low = 100;
const long i_high = 900;

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);

volatile unsigned long clockfcpu = SystemCoreClock;
(void)clockfcpu;
__asm__ volatile("nop");

HAL_RCC_MCOConfig(RCC_MCO, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); // PA8 shows clock
}

void loop() {
// here is where you'd put code that needs to be running all the time.

// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
interval = i_high;
} else {
ledState = LOW;
interval = i_low;
}

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}


RogerClark
Sat Sep 17, 2016 1:24 am
Thanks Rick

I was just posting about the best way to refactor the libstm32f1 folder to accommodate this sort of change

I see you did it using #ifdefs

But I wonder if it would be better to split out the hw_config.c / .h (and the build gcc ) etc into separate folders

e.g. system/variants/bluepill would contain source and include and build_cc and (with the hw_config files in those source and include folders)

Or perhaps put the variants folder inside libstm32f1

I’m not desperately keen on ifdef’s as I have seen it get very messy e.g. for some Arduino libraries, where they try to support multiple platforms


Rick Kimball
Sat Sep 17, 2016 2:51 pm
I’m really just trying stuff out here to get a feel for the code base. With the latest changes, I moved the hw_config.c to each of the variants folder. This seems to be a workable approach.

RogerClark
Sat Sep 17, 2016 9:08 pm
Thanks Rick

RogerClark
Sun Sep 18, 2016 12:29 am
Rick

I tried your repo and it works fine, just with moving hw_config.c

I tried to also move hw_config.h, but that didnt work as its by some of the files in libstm32f1

I think perhaps we should go with this method as a first pass and see whether there are any issues with it, e.g. whether there will be any changes which require hw_config.h to be changed.

I suspect we’ll find out very soon, as adding USB Serial (USB CDCACM) is whats going to be needed next, and I’m sure it will highlight any issues ;-)

PS.

I also copied all the tools from the libmaple repo so that I could directly upload from the IDE via STLink, and they worked OK (not surprisingly)

I know the tools probably need some tidying up, but I may still just copy them all over into the STM core, so that at least we have something.

But I will see if I can discuss all these changes with Frederic on Monday, assuming he’s not gone on paternity leave yet.


RogerClark
Sun Sep 18, 2016 11:34 am
Rick

Actually

Can you create a PR and I’ll pull your version. (I’m not sure if I can pull without a PR.. I think I can just pull and merge, but as you did all the work on this, it would be better if you were credited)

Once I’ve pulled your changes, I am going to push all of the existing tools and update the boards.txt to allow the various upload selections for the BluePill

Well, not the bootloader upload as we don’t have USB Serial yet.


Rick Kimball
Sun Sep 18, 2016 3:00 pm
I created a pull request. Note: This really needs its pin map sorted. I didn’t do that yet. The only pin I actually tested was the LED.

https://github.com/stm32duino/Arduino_C … 2F1/pull/2

I cancelled this request until I fix up the pin map


Slammer
Sun Sep 18, 2016 5:47 pm
IMO, we can live without arduino pinmap for now… let it roll…

Rick Kimball
Sun Sep 18, 2016 7:52 pm
Slammer wrote:IMO, we can live without arduino pinmap for now… let it roll…

RogerClark
Sun Sep 18, 2016 8:51 pm
Whats wrong with the pin map ?

I tried the standard blink and it seemed to work using PC13 ( but I better double check)


Rick Kimball
Sun Sep 18, 2016 9:34 pm
i dont’t think analog functions will work

RogerClark
Sun Sep 18, 2016 9:49 pm
Rick

OK.

Thanks.

I just took a quick look at the pin declarations in variant.cpp and see you defined PC13.

I wonder why they had the “Arduino_id” in the pin map

typedef struct _PinDescription
{
uint32_t arduino_id;
uint32_t ulPin ;
GPIO_TypeDef * ulPort;
uint32_t mode;
bool configured;
} PinDescription ;


RogerClark
Sun Sep 18, 2016 10:53 pm
Re: Analog

I see what you mean

There are some pins e.a. PA6, PA7 etc that could have ADC but the “mode” doesnt have ADC specified for those pins

But I can’t find anything in the code which actually uses the definition GPIO_PIN_ADC

The only “modes” that seem to be actively used in the code are GPIO_PIN_PWM and GPIO_PIN_DAC , albeit, I’m only looking in the F1 (but as they are self contained cores, thats all that matters.

Edit

I noticed you’bve changed the MAX_DIGITAL_IOS

And I’ve noticed that we’d need to change any reference to ARDUINO_PIN_xx as I’ve removed them and replaced with the Pxx definitions

Edit 2

I think the best thing to do is for me to pull to a new branch and then make those changes. @slammer etc can then test that branch before its merged back into the master


Slammer
Sun Sep 18, 2016 11:36 pm
ARDUINO_PINS are the corresponding pins on NUCLEO boards (they have arduino uno pinout). They are used just for compatibility with arduino programs (when it is possible). In blue pill they are not needed as there is no relation with arduino numbering. It is better to keep the standard STM32 pin namming (PA1, PA2, PA3 etc…) and if a variant has “arduino pins” to make some extra defines for this.
For example it is possible to keep a predefined type of numbering eg:

PA0 = Port A, Pin 0 = Number 0x00
PA1 = Port A, Pin 1 = Number 0x01
.
.
PB0 = Port B, Pin 0 = Number 0x10
PB1 = Port B, Pin 1 = Number 0x11

First Nibble = Port
Second Nibble = Pin Number
This scheme would be useful as the number of the pin, keeps info about port and pin position (this will help to optimise some functions and/or reduce the size of some structures)


RogerClark
Mon Sep 19, 2016 12:07 am
@slammer

The PIN_ARDUINO_XXX seems to be used in some other macro’s in the same file, so it will all need to be updated for the BluePill etc

I’m busy with work this morning, but I”ll pull Ricks changes to a new branch of the Arduino_Core_STM32F1 repo, this afternoon (or evening), and try to change everything in variant.c, so that tomorrow you guys can give it a try.

Note. We need to get USB Serial working as well.

I know @Vassilis got it working with the HAL MX core that @sheepdoll created, so I’m hoping we can re-used or leverage a lot of his code.

(Though we may also need to re-export the HAL code from the Cube, as I’m not sure whether all the necessary HAL functions were exported as the were not required for the Nucleo board :-(


evge.05
Mon Sep 19, 2016 5:04 am
Hello! Try to use button on PC13. But sketch doesn’t compile. Whith Rogers core every thing is fine, but whith this core some things is wrong. As I understand here we can use only arduino pins A0-A5, D0-D15? Port C not defined in this core? Am I right?

RogerClark
Mon Sep 19, 2016 5:17 am
Rick defined PC13 but I only tried it for output, there may be something else in the code that prevents it from being used as an input

evge.05
Mon Sep 19, 2016 7:40 am
HAL_GPIO:5: error: 'PC13' was not declared in this scope

RogerClark
Mon Sep 19, 2016 7:44 am
Which core are you using? The one in Rick’s repo ?

evge.05
Mon Sep 19, 2016 7:49 am
Yes. On Your core same sketch compiling and working.

RogerClark
Mon Sep 19, 2016 8:28 am
How did you install the core ?

evge.05
Mon Sep 19, 2016 9:45 am
like your core. Just copy files into /arduino/hardware/

RogerClark
Mon Sep 19, 2016 10:01 am
OK

Can you confirm which URL you downloaded it from ?


evge.05
Mon Sep 19, 2016 10:24 am
https://github.com/RickKimball/Arduino_Core_STM32F1

RogerClark
Mon Sep 19, 2016 11:21 am
Um

Thats strange

I don’t get that error

What version of the IDE are you running ?


evge.05
Mon Sep 19, 2016 11:51 am
latest version 1.6.11

Rick Kimball
Mon Sep 19, 2016 12:05 pm
https://github.com/RickKimball/Arduino_ … /variant.h
PC13 is in that file.

Did you select the blue pill board or the nucleo?


evge.05
Mon Sep 19, 2016 12:08 pm
select a nucleo board

Rick Kimball
Mon Sep 19, 2016 12:09 pm
then you need to use whatever pin is for the led on that board in place of the PC13.

Rick Kimball
Mon Sep 19, 2016 12:16 pm
I guess i should have used the define LED_BUILTIN however the way I wrote the code it was specific to the blue pill as it turns the led on by setting it low for 100ms then turns it off for 900 ms by setting the pin high. If you try that on a nucleo board it will be mostly on 90% of the time.

evge.05
Mon Sep 19, 2016 12:26 pm
i’ve just reinstall arduino IDE and copied core again. But arduino IDE doesn’t see new core whith nucleo boards. Rogers core works fine. Very strange things.
sorry. Maybe I’ve made somethings wrong, but this core works only if it copy to folder whith Rogers core https://github.com/rogerclarkmelbourne/Arduino_STM32 In other case arduino IDE doesn’t see Rick core.

Rick Kimball
Mon Sep 19, 2016 1:09 pm
I have mine extracted to :
Arduino/hardware/st/stm32f1

following the vendor/architecture model from

https://github.com/arduino/Arduino/wiki … 1.0-to-1.6


evge.05
Mon Sep 19, 2016 1:19 pm
well, i’ve extracted to /documents/Arduino/Hardware/stm32f1-master – doesn’t work. Than i’ve extracted Rogers core to /documents/Arduino/Hardware/stm32f1 – everything is work. Than i’ve copied Rick core to /documents/Arduino/hardware/stm32f1/ and it appears in arduino ide.

Rick Kimball
Mon Sep 19, 2016 1:29 pm
Probably the right place would be:

$ pwd
/home/kimballr/Arduino/hardware/stm32duino/stm32f1
$ ls
boards.txt cores libraries platform.txt programmers.txt README.md system variants

where stm32duino is the vendor
and stm32f1 is the architecture

For linux it looks like this:
$ mkdir -p $HOME/Arduino/hardware/stm32duino
$ cd $HOME/Arduino/hardware/stm32duino
$ git clone https://github.com/RickKimball/Arduino_Core_STM32F1.git stm32f1
$ ls stm32f1
boards.txt cores libraries platform.txt programmers.txt README.md system variants


evge.05
Mon Sep 19, 2016 1:35 pm
i’m win10 user.

Rick Kimball
Mon Sep 19, 2016 1:40 pm
So I guess it needs to end up in:

C:\someuserdir\Documents\Arduino\hardware\stm32duino\stm32f1\boards.txt ?


evge.05
Mon Sep 19, 2016 1:57 pm
C:\Users\evgen\Documents\Arduino\hardware\Arduino_STM32-master\ArduinoSTM32F1\boards.txt – this variant is work.
C:\Users\evgen\Documents\Arduino\hardware\ArduinoSTM32F1\boards.txt – this variant doesn’t work.

Rick Kimball
Mon Sep 19, 2016 7:31 pm
RogerClark wrote:
I wonder why they had the “Arduino_id” in the pin map

Rick Kimball
Mon Sep 19, 2016 7:36 pm
Before I spend too much time on this, I’ll wait for the ST team to declare victory and indicate they are done. Do you plan on doing anything more with the STM32F1 code @fpiSTM ?

-rick


RogerClark
Mon Sep 19, 2016 8:28 pm
Rick did you see the post from Wi6labs?

I moved it to this section.


Rick Kimball
Mon Sep 19, 2016 8:30 pm
I didn’t see that post. Thanks.

RogerClark
Tue Sep 20, 2016 8:28 am
Rick

I emailed Frederic and Laurent @ STM, and Frederic confirmed that they do not intend to make any changes to the cores which they have released.

And as you can see from Wi6Lab’s post, they would only change the F1 code if a bug was reported.

But as I expect our changes will effect the files used to create the Nucleo, I doubt if any bugs could be referred back to them, unless it was part of the core and not the Variant.

Looking at the files, I think we’re probably going to have to live with a certain amount of duplication, as the variants may need changes in virtually all the files in the libstm32f1/source folder

So we may have to put a variants folder inside libstm32f1 and copy the files into each variant.

Perhaps @Slammer and a few other people could look at it as well (perhaps @sheepdoll etc) as this will hopefully see any potential problems


danieleff
Tue Sep 20, 2016 9:01 am
What if you only put the periphery definition structs (g_analog_config, spi_init_info, g_uart_config, …) to the variant file?

RogerClark
Tue Sep 20, 2016 10:00 am
I took a quick look at analog.c and it does look as if its just that struct which contains the variant definitions, however in

HAL_DAC_MspInit()

There is this code

if(g_analog_config[g_current_init_id].port == GPIOA) {
__GPIOA_CLK_ENABLE();
} else if(g_analog_config[g_current_init_id].port == GPIOB){
__GPIOB_CLK_ENABLE();
} else if(g_analog_config[g_current_init_id].port == GPIOC){
__GPIOC_CLK_ENABLE();
}


Rick Kimball
Tue Sep 20, 2016 1:05 pm
danieleff wrote:What if you only put the periphery definition structs (g_analog_config, spi_init_info, g_uart_config, …) to the variant file?

Rick Kimball
Tue Sep 20, 2016 1:08 pm
RogerClark wrote:
if(g_analog_config[g_current_init_id].port == GPIOA) {
__GPIOA_CLK_ENABLE();
} else if(g_analog_config[g_current_init_id].port == GPIOB){
__GPIOB_CLK_ENABLE();
} else if(g_analog_config[g_current_init_id].port == GPIOC){
__GPIOC_CLK_ENABLE();
}

Slammer
Tue Sep 20, 2016 3:33 pm
Can be changed to something like that:
if(port == GPIOA) {
__GPIOA_CLK_ENABLE();
} else if(port == GPIOB){
__GPIOB_CLK_ENABLE();
} else if(port == GPIOC){
__GPIOC_CLK_ENABLE();
}
#ifdef GPIOD
} else if(port == GPIOD){
__GPIOD_CLK_ENABLE();
}
#endif
#ifdef GPIOE
} else if(port == GPIOE){
__GPIOE_CLK_ENABLE();
}
#endif

rreignier
Tue Sep 20, 2016 5:35 pm
Slammer wrote:Can be changed to something like that:
if(port == GPIOA) {
__GPIOA_CLK_ENABLE();
} else if(port == GPIOB){
__GPIOB_CLK_ENABLE();
} else if(port == GPIOC){
__GPIOC_CLK_ENABLE();
}
#ifdef GPIOD
} else if(port == GPIOD){
__GPIOD_CLK_ENABLE();
}
#endif
#ifdef GPIOE
} else if(port == GPIOE){
__GPIOE_CLK_ENABLE();
}
#endif

RogerClark
Tue Sep 20, 2016 8:55 pm
I think libmaple has similar code, based on the MCU “density”

I guess we should start making these non invasive changes, as I dont think it will have any impact on the function of the Nucleo library


RogerClark
Thu Sep 22, 2016 9:49 pm
Guys

Just to get the ball moving, I’m going to duplicate libstm32f1 to make libBluePill, I’ll manually merge Rick’s changes

I know this means there is a lot of duplication, but it means we are free to change any files without fear it will cause problems to the Nucleo.

We can always optimise the file duplication issue at a later date.

I also have to upload all the other tools e.g. stlink upload

I will post then its done (probably some time on Saturday,but I may have time to do it today)


RogerClark
Sat Sep 24, 2016 12:17 pm
See http://www.stm32duino.com/viewtopic.php … 227#p18227

RogerClark
Wed Sep 28, 2016 11:30 am
FYI

Info from Wi6Labs, They use these versions of “Firmware” in the Cube

1.4.0 STM32CubeF1 and the 1.4.0 STM32CubeL4.

So removed some older “firmware” versions from my cube and made sure I only had these…. As I sometimes need to export files e.g. USB etc from the Cube for use in this core


danieleff
Tue Oct 11, 2016 7:37 am
danieleff wrote:What if you only put the periphery definition structs (g_analog_config, spi_init_info, g_uart_config, …) to the variant file?

RogerClark
Tue Oct 11, 2016 8:39 am
Thanks

I’m not sure how much space would be saved my removing elements from the structs, I guess it depends on how much can be removed.

I recall looking at something similar in libmaple and it wasnt wasting that much space, but this is probably different

Re: Pin config between variants

I think libmaple inits all possible gpios even for the lowest variant. Perhaps not technically correct but it saves a lot of duplicated code and doesnt seem to do any harm if the device doesn’t actually have that hardware


stevestrong
Tue Oct 11, 2016 9:07 am
danieleff wrote:The size of the structs can be greatly reduced. The pin speed/pull/mode can be removed in SPI/I2C/UART, I dont think they change. The GPIO_CLKx_ENABLE can be removed by calling digital_io_init() instead of HAL_GPIO_Init().

danieleff
Tue Oct 11, 2016 9:26 am
stevestrong wrote:danieleff wrote:The size of the structs can be greatly reduced. The pin speed/pull/mode can be removed in SPI/I2C/UART, I dont think they change. The GPIO_CLKx_ENABLE can be removed by calling digital_io_init() instead of HAL_GPIO_Init().

danieleff
Sun Oct 23, 2016 6:56 pm
These structs can be automatically generated using the CubeMX data xml files. I wrote a python script that can extract SPI data into C code: http://pastebin.com/85JCVk9K , Usage:set the cubemx_dir variable, and run it as: python cubemx_data_export.py STM32F103C8
Examples of generated code: STM32F103C8, STM32L476RG, STM32F746BE

UART/I2C (or even gpio list in variant) can be easily done. ADC/DAC/PWM a maybe little harder. Timers … I did not look into it.
It generates the default pins. There is a “remaps” at the bottom to help set up alternate pins.


danieleff
Sun Nov 13, 2016 9:40 am
And here are some generated files for boards: https://github.com/danieleff/Arduino_Co … n_examples
While the first SPI/I2C… pins are mostly the same, if you ever want to use alternate pins / multiple SPI-s etc… it will be easier to generate than configuring all of them by hand.
These are just examples but they are the structs used in this core.

RogerClark
Sun Nov 13, 2016 9:51 am
Excellent…

Thanks


Ollie
Sun Nov 13, 2016 5:15 pm
Daniel,

I had not visited your Github previously and now I have to say that I like your programming style a lot. The information you have at

https://github.com/danieleff/Arduino_Core_STM32F1

is very useful for all STM32 developers. There are so huge amount of details that I do wonder, what kind of quality assurance methods you have used to gain confidence that the information is correct.

Cheers, Ollie


RogerClark
Sun Nov 13, 2016 7:23 pm
I will merge Daniel’s repo into the stm32 repo today.

As I already did a local merge of the previous stable commit and it worked fine for me


danieleff
Mon Nov 14, 2016 7:58 am
Ollie wrote:Daniel,

I had not visited your Github previously and now I have to say that I like your programming style a lot. The information you have at

https://github.com/danieleff/Arduino_Core_STM32F1

is very useful for all STM32 developers. There are so huge amount of details that I do wonder, what kind of quality assurance methods you have used to gain confidence that the information is correct.

Cheers, Ollie


RogerClark
Mon Nov 14, 2016 8:18 am
See

viewtopic.php?f=16&t=1553&start=20

Its mostly working.

The only issue at the moment is that the ValueLine Discovery F100 library won’t compile because of the USB files


Leave a Reply

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