Converting a library of Arduino to a Library for STM32 - Page 1
Forum section: electronics / general

author: panoss
author_rank: Frequent Contributor
timestamp: December 04, 2019, 04:24:53 pm
content: (and more specifically, for STM32F030F4P6)I 'm trying to convertArduino 's Lora libraryto STM32 library (Atollic TrueStudio).This is my project 's structure: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:void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);This does not compile as is, so I changed it to:Code: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?

author: GromBeestje
author_rank: Frequent Contributor
timestamp: December 04, 2019, 07:19:46 pm
content: QuoteThe first line? Do you meanCode: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.

author: tmadness
author_rank: Regular Contributor
timestamp: December 04, 2019, 07:29:30 pm
content: 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 thathttps://github.com/stm32duino/wiki/wiki/Getting-Started

author: panoss
author_rank: Frequent Contributor
timestamp: December 04, 2019, 07:43:09 pm
content: Quote from: GromBeestje on December 04, 2019, 07:19:46 pmYes, 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'The PA_OUTPUT_PA_BOOST_PIN is defined.

author: panoss
author_rank: Frequent Contributor
timestamp: December 04, 2019, 07:47:23 pm
content: Quote from: tmadness on December 04, 2019, 07:29:30 pm1. 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.

author: thm_w
author_rank: Super Contributor
timestamp: December 04, 2019, 10:22:55 pm
content: Quote from: panoss on December 04, 2019, 04:24:53 pmGet 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.

author: panoss
author_rank: Frequent Contributor
timestamp: December 05, 2019, 08:22:15 am
content: I changed it to:Code: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!)

author: tmadness
author_rank: Regular Contributor
timestamp: December 05, 2019, 06:25:53 pm
content: 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.

author: mikerj
author_rank: Super Contributor
timestamp: December 05, 2019, 06:45:18 pm
content: Quote from: panoss on December 05, 2019, 08:22:15 amYou have changed the function declaration, that's not what was suggested.Code:#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.

author: panoss
author_rank: Frequent Contributor
timestamp: December 05, 2019, 06:54:10 pm
content: Quote from: mikerj on December 05, 2019, 06:45:18 pmI 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:// deprecatedvoid crc() { enableCrc(); }I get 2 errors:-first defined here-multiple definition of `crc'

author: thm_w
author_rank: Super Contributor
timestamp: December 05, 2019, 11:04:44 pm
content: No need to omit it.. follow mikerj's instructions or change the function:Code:/* 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++.

author: panoss
author_rank: Frequent Contributor
timestamp: December 06, 2019, 01:05:31 pm
content: I 'll just keep the:Code: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:void setSPI(SPIClass& spi);What can I do here?

author: thm_w
author_rank: Super Contributor
timestamp: December 06, 2019, 10:50:05 pm
content: Code: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.

author: panoss
author_rank: Frequent Contributor
timestamp: December 08, 2019, 03:48:32 pm
content: This is 10 lines fromArduino 's SPI.h.Code: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:SPISettings_with_params(uint32_t clock, uint8_t bitOrder, uint8_t dataMode);SPISettings_no_params();

author: thm_w
author_rank: Super Contributor
timestamp: December 10, 2019, 01:05:43 am
content: 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:static SPI_HandleTypeDef spi = { .Instance = SPI1 };spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;spi.Init.Direction = SPI_DIRECTION_2LINES;spi.Init.CLKPhase = SPI_PHASE_2EDGE;spi.Init.CLKPolarity = SPI_POLARITY_HIGH;spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;spi.Init.DataSize = SPI_DATASIZE_8BIT;spi.Init.FirstBit = SPI_FIRSTBIT_MSB;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/

author: bingo600
author_rank: Super Contributor
timestamp: December 10, 2019, 07:53:31 pm
content: Do you think you can squeeze the lora lib & program into 16K flash ??/Bingo

author: panoss
author_rank: Frequent Contributor
timestamp: December 11, 2019, 08:32:23 am
content: O holly ***it!! I never thought of that!This is the output from Arduino 's IDE:But the .hex file, the one without the bootloader (Sketch->Export Compiled binary) is 31KB.

author: bingo600
author_rank: Super Contributor
timestamp: December 11, 2019, 09:58:44 am
content: Quote from: panoss on December 11, 2019, 08:32:23 amYou 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 16KIs ST giving us a "secret gift" of 2 x flash on the 30f4 too/Bingo

author: panoss
author_rank: Frequent Contributor
timestamp: December 11, 2019, 10:55:11 am
content: Quote from: bingo600 on December 11, 2019, 09:58:44 amI '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.

author: bingo600
author_rank: Super Contributor
timestamp: December 11, 2019, 11:12:05 am
content: Quote from: panoss on December 11, 2019, 10:55:11 amWell a 30F4 should have 16K flash according to the Datasheet.But nice if they have 32KYou 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 ??

author: panoss
author_rank: Frequent Contributor
timestamp: December 11, 2019, 11:23:26 am
content: 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.

author: panoss
author_rank: Frequent Contributor
timestamp: December 11, 2019, 08:35:56 pm
content: In the header file (lora.h) exists this code:Code: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: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'.

author: thm_w
author_rank: Super Contributor
timestamp: December 11, 2019, 11:47:36 pm
content: Initializer list:https://en.cppreference.com/w/cpp/language/initializer_list

author: panoss
author_rank: Frequent Contributor
timestamp: December 12, 2019, 01:04:09 pm
content: How about Static cast?Code:freqError = static_cast<int32_t>(readRegister(REG_FREQ_ERROR_MSB) & B111);How do I convert this to C?

author: Nerull
author_rank: Frequent Contributor
timestamp: December 13, 2019, 04:23:43 am
content: 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.

author: panoss
author_rank: Frequent Contributor
timestamp: December 13, 2019, 01:19:38 pm
content: Can 't I just use 0b00000111?

author: Nerull
author_rank: Frequent Contributor
timestamp: December 14, 2019, 12:11:45 am
content: 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.