B4R Tutorial How to Implement STM32 into B4R

If you want more FLASH memory space (say 128K flash), need more RAM (how about 20K), would like your program to run a little faster, or simply want to play around with a different micro-controller family, then have a go at this.

The included PDF document "How to Implement STM32 into B4R.PDF" contains the many steps required to get B4R to compile, upload and run code for a STM32F103RB Nucleo evaluation board.

en.nucleo-F1.jpg


Download the PDF document and get started.

Note:
Now revised 15th December 2016
Improved B4R integration using the existing STM32 library define
_VARIANT_ARDUINO_STM32_
instead of my own define
USING_STM32.
Now revised 11th August 2020
No need to alter the B4R file, Now included in B4R distribution.
See revised "How to Implement STM32 into B4R" document now
up to date with current distribution of STM32 Library.
 

Attachments

  • How to Implement STM32 to B4R.pdf
    207.7 KB · Views: 466
Last edited:

Starchild

Active Member
Licensed User
Longtime User
I have changed the "How to Implement STM32" document.
Available from top post.

Note:
Improved B4R integration using the existing STM32 library define
_VARIANT_ARDUINO_STM32_
instead of my own define
USING_STM32

No need to add or remove a define from the B4R defines template when changing board types.

Wish:
It would now be possible to include the altered "Pin::setMode" code into B4R distribution so no additional patch would be required.

B4X:
    //*******************************************
    void Pin::setMode(Byte arduino_Mode) {
#ifdef _VARIANT_ARDUINO_STM32_
    WiringPinMode stm32_Mode;
    switch (arduino_Mode) {
        case INPUT:
        stm32_Mode = INPUT;
        break;
        case OUTPUT:
        stm32_Mode = OUTPUT;
        break;
        case INPUT_PULLUP:
        stm32_Mode = INPUT_PULLUP;
        break;
    }
    pinMode(PinNumber, stm32_Mode);
#else
    pinMode(PinNumber, arduino_Mode);
#endif
    if (arduino_Mode == INPUT_PULLUP)
        CurrentValue = true;
     }
     //******************************************
 

whcir

Member
Licensed User
Longtime User
Could someone wrap the files for the internal RTC for the STM32? Its looks pretty simple but I don't have the experience.

Thanks
 

Attachments

  • src.zip
    7.4 KB · Views: 411

whcir

Member
Licensed User
Longtime User
I have changed the "How to Implement STM32" document.
Available from top post.

Note:
Improved B4R integration using the existing STM32 library define
_VARIANT_ARDUINO_STM32_
instead of my own define
USING_STM32

No need to add or remove a define from the B4R defines template when changing board types.

Wish:
It would now be possible to include the altered "Pin::setMode" code into B4R distribution so no additional patch would be required.

B4X:
    //*******************************************
    void Pin::setMode(Byte arduino_Mode) {
#ifdef _VARIANT_ARDUINO_STM32_
    WiringPinMode stm32_Mode;
    switch (arduino_Mode) {
        case INPUT:
        stm32_Mode = INPUT;
        break;
        case OUTPUT:
        stm32_Mode = OUTPUT;
        break;
        case INPUT_PULLUP:
        stm32_Mode = INPUT_PULLUP;
        break;
    }
    pinMode(PinNumber, stm32_Mode);
#else
    pinMode(PinNumber, arduino_Mode);
#endif
    if (arduino_Mode == INPUT_PULLUP)
        CurrentValue = true;
     }
     //******************************************

Starchild


Would it be possible to do the same thing with the Serial class and LOG display in board.cpp so when switching between AVR and STM32 I don't have to edit this file every time.

#else
//DEFINE_HWSERIAL(Serial, 3);// Use HW Serial 2 as "Serial"
DEFINE_HWSERIAL(Serial, 2); // changed for B4R
//DEFINE_HWSERIAL(Serial1, 2);
DEFINE_HWSERIAL(Serial1, 3); // changed for B4R
DEFINE_HWSERIAL(Serial2, 1);
#endif
 

Starchild

Active Member
Licensed User
Longtime User
Starchild


Would it be possible to do the same thing with the Serial class and LOG display in board.cpp so when switching between AVR and STM32 I don't have to edit this file every time.

#else
//DEFINE_HWSERIAL(Serial, 3);// Use HW Serial 2 as "Serial"
DEFINE_HWSERIAL(Serial, 2); // changed for B4R
//DEFINE_HWSERIAL(Serial1, 2);
DEFINE_HWSERIAL(Serial1, 3); // changed for B4R
DEFINE_HWSERIAL(Serial2, 1);
#endif
This file "board.cpp" is part of the stm32 library. As such it does not need editting back and forth to use AVR then STM32 devices. The STM32 library is only used when compiling for STM32 devices.
 

Starchild

Active Member
Licensed User
Longtime User
Could someone wrap the files for the internal RTC for the STM32? Its looks pretty simple but I don't have the experience.

Thanks
I have had a look at the RTC class available for STM32. Unfortunately, it relies on the support of hardware interrupts to wake from Sleep. At this time B4R can not support the SLEEP modes of the STM32 making it impossible to support the RTC class.

However, I have created a Generic version of a Software Real Time Clock library for B4R. This is compatible with STM32.
This library is designed to support the features of B4R.
You can download the library (rSoftRtc) from here..

https://www.b4x.com/android/forum/threads/software-real-time-clock.77158/#content
 

derez

Expert
Licensed User
Longtime User
I can see this stm32 implementation is going to be an on going challenge.

I have had a flick through the Arduino_STM32 libraries and I believe that the I2C implementation that has been used is a software emulation of I2C. It does not use the imbedded hardware I2C support of the STM32 chip. As such the rwire library of B4R is not supported. In fact I believe the software emulation of I2C is only for MASTER and not SLAVE mode as there is no provision for a callback.

I have investigated this further and I have had a go of wrapping the Wire class within the Arduino_STM32 library to create a STM32 compatible rwire library for B4R. It only supports MASTER mode. SCL=PB6 and SDA=PB7.

The big unknown is that I don't have any I2C devices to test. Hope it works.

You will need to unpack the ZIP file "stm32_rwire.zip" and copy the contents to your "Additional Libraries" folder. You should have already set this up under B4R menu Tools/Configuration-Paths. Then re-run B4R for this new library to be presented in the Library Manager.

Using SCL=PB6 and SDA=PB7 I can see results on a LCD 1602, it does not use wire library, only LiquidCristal_I2C :)
 

derez

Expert
Licensed User
Longtime User
I can see this stm32 implementation is going to be an on going challenge.

I have had a flick through the Arduino_STM32 libraries and I believe that the I2C implementation that has been used is a software emulation of I2C. It does not use the imbedded hardware I2C support of the STM32 chip. As such the rwire library of B4R is not supported. In fact I believe the software emulation of I2C is only for MASTER and not SLAVE mode as there is no provision for a callback.

I have investigated this further and I have had a go of wrapping the Wire class within the Arduino_STM32 library to create a STM32 compatible rwire library for B4R. It only supports MASTER mode. SCL=PB6 and SDA=PB7.

The big unknown is that I don't have any I2C devices to test. Hope it works.

You will need to unpack the ZIP file "stm32_rwire.zip" and copy the contents to your "Additional Libraries" folder. You should have already set this up under B4R menu Tools/Configuration-Paths. Then re-run B4R for this new library to be presented in the Library Manager.

Using the stm32_rwire library I got error with STM32F103C8T6. I have modified Starchild's library (stm32_rWire.cpp) like this:
B4X:
Byte STM32_WireMaster::WriteTo2(Byte Address, bool SendStop, ArrayByte* Data) {
        Wire.beginTransmission(Address);
        byte b = Data->length;
        Wire.write((Byte*)Data->data, Data->length);
    //    if (SendStop) {
    //        Wire.i2c_stop();
    //    }
    //    Wire.endTransmission();
        Wire.endTransmission(SendStop);
        return b;
}

Now it works without errors and I have connected HMC5883L magnetometer successfuly (connecting SCL to PB6 and SDA to PB7), and MPU6050 IMU as well.
The programs are the same as this https://www.b4x.com/android/forum/t...nts-mpu-6050-and-magnetometer-hmc5883l.65917/
 
Last edited:

Starchild

Active Member
Licensed User
Longtime User
Using the stm32_rwire library I got error with STM32F103C8T6. I have modified Starchild's library (stm32_rWire.cpp) like this:
B4X:
Byte STM32_WireMaster::WriteTo2(Byte Address, bool SendStop, ArrayByte* Data) {
        Wire.beginTransmission(Address);
        byte b = Data->length;
        Wire.write((Byte*)Data->data, Data->length);
    //    if (SendStop) {
    //        Wire.i2c_stop();
    //    }
    //    Wire.endTransmission();
        Wire.endTransmission(SendStop);
        return b;
}

Now it works without errors and I have connected HMC5883L magnetometer successfuly (connecting SCL to PB6 and SDA to PB7), and MPU6050 IMU as well.
The programs are the same as this https://www.b4x.com/android/forum/t...nts-mpu-6050-and-magnetometer-hmc5883l.65917/

Thanks for discovering the fix.
I have updated the download of the "stm32_rwire.zip" library file to include this change now v1.11 at its original posting.
https://www.b4x.com/android/forum/threads/how-to-implement-stm32-into-b4r.68034/#post-433002
 
Top