EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: panoss on December 04, 2019, 04:24:53 pm

Title: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 04, 2019, 04:24:53 pm
(and more specifically, for STM32F030F4P6)
I 'm trying to convert Arduino 's Lora library (https://github.com/sandeepmistry/arduino-LoRa/blob/master/src/LoRa.h) to STM32 library (Atollic TrueStudio).
This is my project 's structure:

[attachimg=1]

The driver consists of Lora.h and Lora.c files.

I have converted the most of the code in the header file (Lora.h) and have commented out (small) parts of the code that don 't compile.

So, I have Arduino 's code:
Code: [Select]
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);This does not compile as is, so I changed it to:
Code: [Select]
int outputPin = PA_OUTPUT_PA_BOOST_PIN;
void setTxPower(int level, int outputPin);

But still does not compile, except if I remove the first line.
What can I do to make it work?
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: GromBeestje on December 04, 2019, 07:19:46 pm
Quote
But still does not compile, except if I remove the first line.

The first line? Do you mean
Code: [Select]
int outputPin = PA_OUTPUT_PA_BOOST_PIN;
You're not very specific on what error you got, but looking at that line, it seems like the only thing that can go wrong there is PA_OUTPUT_PA_BOOST_PIN not being defined. Looking at the URL you gave, it is defined in LoRa.h line 31. 

As it looks this defines a PIN, I might have to rewrite this to define a PIN on your board. For STM32, you might even have to make it PORT and PIN.

Title: Re: Converting a library of Arduino to a Library for STM32
Post by: tmadness on December 04, 2019, 07:29:30 pm
Alright, there are a couple of reasons why this is not compiling:
1. The LORA library is in C++, it looks like you are using C.
2. The Lora library uses Arduino APIs like digitalwrite, spi libraries etc, you've got to modify that stuff too, HAL has somewhat equivalent functions but you've got to figure the right functions and the right configurations. 

So, heavily modify the library so that its compatible OR try using the Arduino core  (if one is available for your MCU) for STM32, info on that https://github.com/stm32duino/wiki/wiki/Getting-Started
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 04, 2019, 07:43:09 pm
Quote
But still does not compile, except if I remove the first line.

The first line? Do you mean
Code: [Select]
int outputPin = PA_OUTPUT_PA_BOOST_PIN;
You're not very specific on what error you got, but looking at that line, it seems like the only thing that can go wrong there is PA_OUTPUT_PA_BOOST_PIN not being defined. Looking at the URL you gave, it is defined in LoRa.h line 31. 

As it looks this defines a PIN, I might have to rewrite this to define a PIN on your board. For STM32, you might even have to make it PORT and PIN.

Yes, this is the line I mean.
A weird fault appears (multiple definition of 'implicitHeader'. I checked, there 's no multiple definition.), at 'void SystemClock_Config'

[attachimg=1]

The PA_OUTPUT_PA_BOOST_PIN is defined.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 04, 2019, 07:47:23 pm
Alright, there are a couple of reasons why this is not compiling:
1. The LORA library is in C++, it looks like you are using C.
2. The Lora library uses Arduino APIs like digitalwrite, spi libraries etc, you've got to modify that stuff too, HAL has somewhat equivalent functions but you've got to figure the right functions and the right configurations. 

So, heavily modify the library so that its compatible OR try using the Arduino core  (if one is available for your MCU) for STM32, info on that https://github.com/stm32duino/wiki/wiki/Getting-Started
1. Yes I know that Arduino is C++ and STM3 is C.
2. Yes, I know, but I am at the header file (Lora.h). This file only has definitions of variables and functions. The 99% of this file compiles as is. Only a few lines don't, like the one I mentioned.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: thm_w on December 04, 2019, 10:22:55 pm

Code: [Select]
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);This does not compile as is, so I changed it to:
Code: [Select]
int outputPin = PA_OUTPUT_PA_BOOST_PIN;
void setTxPower(int level, int outputPin);

Get rid of the first line and either:
- call setTxPower(level, PA_OUTPUT_PA_BOOST_PIN);
- change setTxPower function to always use PA_OUTPUT.. pin as its value.

The original C++ code is defining a default value, if no value is passed to the function. You do not need to replicate that feature.


IMO what usually is a better option is leave the arduino code as-is, and re-implement the missing functions with your own code. Overhead is higher but keeps things simple.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 05, 2019, 08:22:15 am
I changed it to:
Code: [Select]
void setTxPower(int level, PA_OUTPUT_PA_BOOST_PIN);

But I get this error:
"../Inc/Lora.h:30:33: error: expected declaration specifiers or '...' before numeric constant"

And says that PA_OUTPUT_PA_BOOST_PIN is a...macro!! (while it 's a constant!)

[attachimg=1]

Title: Re: Converting a library of Arduino to a Library for STM32
Post by: tmadness on December 05, 2019, 06:25:53 pm
Ya... in C you cant do that, you are setting a function input in the function definition, in C++ its called  a default. Also in terms of naming #defines are pre processor macros, i.e they unraveled/ substituted before compilation. So at compilation time your function looks like void setTxPower( int level, 1) which makes no sense to the compiler as a function prototype.   
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: mikerj on December 05, 2019, 06:45:18 pm
I changed it to:
Code: [Select]
void setTxPower(int level, PA_OUTPUT_PA_BOOST_PIN);

But I get this error:
"../Inc/Lora.h:30:33: error: expected declaration specifiers or '...' before numeric constant"

And says that PA_OUTPUT_PA_BOOST_PIN is a...macro!! (while it 's a constant!)


You have changed the function declaration, that's not what was suggested.

Code: [Select]

#define PA_OUTPUT_PA_BOOST_PIN 1

/* Function declaration */
void setTxPower(int level, int outputPin);

/* Function definition */
void setTxPower(int level, int outputPin)
{
  /* blah...*/
}


/* Function being called */
void main ( void )
{
    setTxPower( 100, PA_OUTPUT_PA_BOOST_PIN  );

}

The problem here is that Arduino can specify any pin using a simple int, although the mechanism to do so is slow and clunky.  If you want to retain this ability you will have to port the Arduino pin handling code to your project as well.  That's why it was suggested that you drop this feature unless you really need it, or use an alternative method e.g. a struct holding a pointer to a port and a bitmask for the pin.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 05, 2019, 06:54:10 pm
That's why it was suggested that you drop this feature unless you really need it
I think I don't really need it for now, so I can just omit this function? (the setTxPower)

I commented it out.

Now, I have this code:
void enableCrc();
Code: [Select]
// deprecated
void crc() { enableCrc(); }

I get 2 errors:
-first defined here   
-multiple definition of `crc'   



Title: Re: Converting a library of Arduino to a Library for STM32
Post by: thm_w on December 05, 2019, 11:04:44 pm
No need to omit it.. follow mikerj's instructions or change the function:

Code: [Select]
/* Function declaration */
void setTxPower(int level);

/* Function definition */
void setTxPower(int level)
{
do_whatever_to_set_pin(PA_OUTPUT_PA_BOOST_PIN);
}

Anyway, search for 'crc' as it is either not properly defined or defined somewhere else in your code.
You may want to spend some time to learn about C++.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 06, 2019, 01:05:31 pm
I 'll just keep the:
Code: [Select]
void crc();I will just place the actual code of 'enableCrc()' crc function.

Now, I think this is really hard as it uses a class (Arduino 's SPI class) and C has no classes:
Code: [Select]
void setSPI(SPIClass& spi);


What can I do here?
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: thm_w on December 06, 2019, 10:50:05 pm
Code: [Select]
void setSPI(SPI_HandleTypeDef* spi)
The functions inside will have to change as well.
It sounds like setup though? So that may have been done already elsewhere in your code.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 08, 2019, 03:48:32 pm
This is 10 lines from Arduino 's  SPI.h (https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/SPI/src/SPI.h).
Code: [Select]
class SPISettings {
public:
    SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
    if (__builtin_constant_p(clock)) {
      init_AlwaysInline(clock, bitOrder, dataMode);
    } else {
      init_MightInline(clock, bitOrder, dataMode);
    }
  }
  SPISettings() {
    init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
  }

The class 'SPISettings' has two constructors ('SPISettings') but taking different parameters?
How do I create the respective C code?

Something like this maybe?
Two functions?
Code: [Select]
SPISettings_with_params(uint32_t clock, uint8_t bitOrder, uint8_t dataMode);
SPISettings_no_params(); 
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: thm_w on December 10, 2019, 01:05:43 am
I would get rid of the second SPISettings().
But those settings (MSBFIRST, SPI_MODE0) are going to be passed further down the rabbit hole. Its something you will have to write yourself or use alternate code anyway.

eg HAL:
Code: [Select]
    static SPI_HandleTypeDef spi = { .Instance = SPI1 };
    spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
    spi.Init.Direction = SPI_DIRECTION_2LINES;
    spi.Init.CLKPhase = [b]SPI_PHASE_2EDGE[/b];
    spi.Init.CLKPolarity = [b]SPI_POLARITY_HIGH[/b];
    spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
    spi.Init.DataSize = SPI_DATASIZE_8BIT;
    spi.Init.FirstBit = [b]SPI_FIRSTBIT_MSB[/b];
    spi.Init.NSS = SPI_NSS_SOFT;
    spi.Init.TIMode = SPI_TIMODE_DISABLED;
    spi.Init.Mode = SPI_MODE_MASTER;
    if (HAL_SPI_Init(&spi) != HAL_OK)
    {
        asm("bkpt 255");
    }
https://visualgdb.com/tutorials/arm/stm32/spi/
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: bingo600 on December 10, 2019, 07:53:31 pm
Do you think you can squeeze the lora lib & program into 16K flash ??

/Bingo
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 11, 2019, 08:32:23 am
O holly ***it!! I never thought of that!
This is the output from Arduino 's IDE:

[attachimg=1]

But the .hex file, the one without the bootloader (Sketch->Export Compiled binary) is 31KB. :wtf:
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: bingo600 on December 11, 2019, 09:58:44 am
O holly ***it!! I never thought of that!
This is the output from Arduino 's IDE:

(Attachment Link)

But the .hex file, the one without the bootloader (Sketch->Export Compiled binary) is 31KB. :wtf:

You should believe the IDE (bin size) , and NOT the hex size , the hex is converted to binary before programming the chip , and that reduces the size by more than a faxtor 2.

Your IDE is reporting 32K flash , where it should be 16K
[attachimg=1]

Is ST giving us a "secret gift" of 2 x flash on the 30f4 too  :-+

/Bingo
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 11, 2019, 10:55:11 am
Your IDE is reporting 32K flash , where it should be 16K
I 'm not using the STM32 with the Arduino IDE but, as I mentioned, with TrueSTUDIO.

I 'm using the Arduino with the Arduino IDE. So it 's correctly reporting 32K flash.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: bingo600 on December 11, 2019, 11:12:05 am
Your IDE is reporting 32K flash , where it should be 16K
I 'm not using the STM32 with the Arduino IDE but, as I mentioned, with TrueSTUDIO.

I 'm using the Arduino with the Arduino IDE. So it 's correctly reporting 32K flash.

Well a 30F4 should have 16K flash according to the Datasheet.
But nice if they have 32K

You write you use Atollic , but shows a screenshot of Arduino IDE ... I'm confused.

Ahh ... Are you showing the flash usage for an AVR M328 when using the Arduino ide , for size comparison ??
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 11, 2019, 11:23:26 am
I 'm showing a screenshot of the Arduino IDE that displays the size of the program in Arduino (ATMega328p).
Sorry for not being clear enough.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 11, 2019, 08:35:56 pm
In the header file (lora.h) exists this code:
Code: [Select]
private:
  SPISettings _spiSettings;
  SPIClass* _spi;
  int _ss;
  int _reset;
  int _dio0;
  long _frequency;

The important part is the 'long _frequency'. Ignore the rest of the variables.

Then in the constructor of the class (in file lora.cpp):
Code: [Select]
LoRaClass::LoRaClass() :
  _spiSettings(LORA_DEFAULT_SPI_FREQUENCY, MSBFIRST, SPI_MODE0),
  _spi(&LORA_DEFAULT_SPI),
  _ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN),
  _frequency(0),

The important part is the ' _frequency(0)'.

The _frequency is a variable and it 's used like if it 's a function? :-//
What does it mean? '_frequency=0' or something else?
What 's the equivalent in C?


EDIT: I tested the value of '_frequency' after it's initialization in the constructor and I concluded that '_frequency(0)' is the same as '_frequency=0'.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: thm_w on December 11, 2019, 11:47:36 pm
Initializer list: https://en.cppreference.com/w/cpp/language/initializer_list
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 12, 2019, 01:04:09 pm
How about Static cast?
Code: [Select]
freqError = static_cast<int32_t>(readRegister(REG_FREQ_ERROR_MSB) & B111);
How do I convert this to C?
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: Nerull on December 13, 2019, 04:23:43 am
freqError = (int32_t)(readRegister(REG_FREQ_ERROR_MSB) & B111);

B111 is a macro in the arduino headers to kinda sorta replicate binary literals which aren't part of the C standard but are supported by GCC in the format 0b111, you might need to be replace that. The C standard compliant version would be to use a hex literal as in 0x7 or just 7 decimal.
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: panoss on December 13, 2019, 01:19:38 pm
Can 't I just use 0b00000111?
Title: Re: Converting a library of Arduino to a Library for STM32
Post by: Nerull on December 14, 2019, 12:11:45 am
In GCC you can, in but that format isn't technicality valid C and may not be as portable. They were added to the C++ standard in C++14 but are not in the C standard as of C18.