Skip to content

Commit

Permalink
Added initial support to STM32 (using CubeHAL API).
Browse files Browse the repository at this point in the history
  • Loading branch information
colombojrj committed Aug 16, 2022
1 parent 89358b2 commit 8656ba7
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 3 deletions.
46 changes: 44 additions & 2 deletions RF24.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ void RF24::csn(bool mode)
#endif // defined(RF24_RPi)

#if !defined(RF24_LINUX)
#if defined(STM32)
HAL_GPIO_WritePin(csn_port, csn_pin, mode ? GPIO_PIN_SET : GPIO_PIN_RESET);
#else
digitalWrite(csn_pin, mode);
#endif
delayMicroseconds(csDelay);
#else
static_cast<void>(mode); // ignore -Wunused-parameter
Expand All @@ -104,7 +108,11 @@ void RF24::ce(bool level)
{
//Allow for 3-pin use on ATTiny
if (ce_pin != csn_pin) {
#if defined(STM32)
HAL_GPIO_WritePin(ce_port, ce_pin, level ? GPIO_PIN_SET : GPIO_PIN_RESET);
#else
digitalWrite(ce_pin, level);
#endif
}
}

Expand Down Expand Up @@ -593,7 +601,7 @@ void RF24::_init_obj()
{
// Use a pointer on the Arduino platform

#if defined(RF24_SPI_PTR) && !defined(RF24_RP2)
#if defined(RF24_SPI_PTR) && !defined(RF24_RP2) && !defined(STM32)
_spi = &SPI;
#endif // defined (RF24_SPI_PTR)

Expand Down Expand Up @@ -945,7 +953,7 @@ void RF24::encodeRadioDetails(uint8_t* encoded_details)
#endif // !defined(MINIMAL)

/****************************************************************************/
#if defined(RF24_SPI_PTR) || defined(DOXYGEN_FORCED)
#if (defined(RF24_SPI_PTR) || defined(DOXYGEN_FORCED)) && !defined(STM32)
// does not apply to RF24_LINUX

bool RF24::begin(_SPI* spiBus)
Expand All @@ -967,6 +975,20 @@ bool RF24::begin(_SPI* spiBus, uint16_t _cepin, uint16_t _cspin)

/****************************************************************************/

#if defined(STM32)
bool RF24::begin(SPI_HandleTypeDef * spiBus, uint16_t _cepin, GPIO_TypeDef* _ceport, uint16_t _cspin, GPIO_TypeDef* _csport)
{
ce_pin = _cepin;
ce_port = _ceport;
csn_pin = _cspin;
csn_port = _csport;
_spi = new DummySpi(spiBus);
return begin();
}
#endif

/****************************************************************************/

bool RF24::begin(uint16_t _cepin, uint16_t _cspin)
{
ce_pin = _cepin;
Expand Down Expand Up @@ -1001,6 +1023,11 @@ bool RF24::begin(void)
#elif defined(RF24_RP2)
_spi->begin(PICO_DEFAULT_SPI ? spi1 : spi0);

#elif defined(STM32)
// you should configure the spi handler outside because your microcontroller may have more than one spi bus
_spi->begin();
spi_speed = _spi->get_baud();

#else // using an Arduino platform || defined (LITTLEWIRE)

#if defined(RF24_SPI_PTR)
Expand Down Expand Up @@ -1046,6 +1073,21 @@ bool RF24::_init_pins()
csn(HIGH);
delay(200);

#elif defined(STM32)
if (ce_pin != csn_pin) {
GPIO_InitTypeDef gpio;
gpio.Speed = GPIO_SPEED_FREQ_HIGH;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Pin = ce_pin;
HAL_GPIO_Init(ce_port, &gpio);
gpio.Pin = csn_pin;
HAL_GPIO_Init(csn_port, &gpio);
}

ce(LOW);
csn(HIGH);

#else // using an Arduino platform

// Initialize pins
Expand Down
35 changes: 34 additions & 1 deletion RF24.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ class RF24

uint16_t ce_pin; /* "Chip Enable" pin, activates the RX or TX role */
uint16_t csn_pin; /* SPI Chip select */

#if defined(STM32)
GPIO_TypeDef* ce_port;
GPIO_TypeDef* csn_port;
#endif

uint32_t spi_speed; /* SPI Bus Speed */
#if defined(RF24_LINUX) || defined(XMEGA_D3) || defined(RF24_RP2)
uint8_t spi_rxbuff[32 + 1]; //SPI receive buffer (payload max 32 bytes)
Expand Down Expand Up @@ -242,7 +248,7 @@ class RF24
*/
bool begin(void);

#if defined(RF24_SPI_PTR) || defined(DOXYGEN_FORCED)
#if (defined(RF24_SPI_PTR) || defined(DOXYGEN_FORCED)) && !defined(STM32)
/**
* Same as begin(), but allows specifying a non-default SPI bus to use.
*
Expand Down Expand Up @@ -284,6 +290,33 @@ class RF24
bool begin(_SPI* spiBus, uint16_t _cepin, uint16_t _cspin);
#endif // defined (RF24_SPI_PTR) || defined (DOXYGEN_FORCED)

#if defined(STM32)
/**
* Same as begin(), but allows dynamically specifying a SPI bus, CE pin,
* and CSN pin to use.
*
* @note This function assumes the `SPI::begin()` method was called before to
* calling this function.
*
* @warning This function is for the Arduino platforms only
*
* @param spiBus A pointer or reference to an instantiated SPI bus object.
* The `_SPI` datatype is a "wrapped" definition that will represent
* various SPI implementations based on the specified platform.
* @param _cepin The pin attached to Chip Enable on the RF module.
* @param _ceport The handle object associated with the pin attached to Chip Enable on the RF module.
* @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module.
* @param _csport The handle object associated with the pin attached to Chip Select (often labeled CSN) on the radio module.
* - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI)
* is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for the radio's CSN pin.
*
* @see Review the [Arduino support page](md_docs_arduino.html).
*
* @return same result as begin()
*/
bool begin(SPI_HandleTypeDef * spiBus, uint16_t _cepin, GPIO_TypeDef* _ceport, uint16_t _cspin, GPIO_TypeDef* _csport);
#endif

/**
* Same as begin(), but allows dynamically specifying a CE pin
* and CSN pin to use.
Expand Down
9 changes: 9 additions & 0 deletions RF24_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@
#include "utility/rp2/RF24_arch_config.h"
#define sprintf_P sprintf

#elif (defined(STM32))
#include "utility/stm32/RF24_arch_config.h"

#ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({ x; })
#else
#define IF_SERIAL_DEBUG(x)
#endif // SERIAL_DEBUG

#elif (!defined(ARDUINO)) // Any non-arduino device is handled via configure/Makefile
// The configure script detects device and copies the correct includes.h file to /utility/includes.h
// This behavior can be overridden by calling configure with respective parameters
Expand Down
99 changes: 99 additions & 0 deletions utility/STM32/RF24_arch_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#ifndef RF24_UTILITY_STM32_RF24_ARCH_CONFIG_H
#define RF24_UTILITY_STM32_RF24_ARCH_CONFIG_H


#include <cstdint>
#include <memory.h>


#if defined(STM32F0)
#include "stm32f0xx_hal.h"
#elif defined(STM32F1)
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_gpio.h"
#include "stm32f1xx_hal_spi.h"
#elif defined(STM32F4)
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_gpio.h"
#elif defined(STM32L0)
#include "stm32l0xx_hal.h"
#elif defined(STM32L1)
#include "stm32l1xx_hal.h"
#elif defined(STM32L4)
#include "stm32l4xx_hal.h"
#elif defined(STM32F3)
#include "stm32f3xx_hal.h"
#elif defined(STM32H7)
#include "stm32h7xx_hal.h"
#elif defined(STM32F7)
#include "stm32f7xx_hal.h"
#elif defined(STM32G0)
#include "stm32g0xx_hal.h"
#elif defined(STM32G4)
#include "stm32g4xx_hal.h"
#endif


#if !defined(PROGMEM)
#define PROGMEM
#endif

#if !defined(HIGH)
#define HIGH true
#endif

#if !defined(LOW)
#define LOW false
#endif

#if !defined(millis)
#define millis HAL_GetTick
#endif

#if !defined(delayMicroseconds)
void delayMicroseconds(uint32_t usecs);
#endif

#if !defined(delay)
#define delay(msecs) delayMicroseconds(1000*msecs)
#endif

#if !defined(_BV)
#define _BV(bit) (1<<(bit))
#endif

#if !defined(PSTR)
#define PSTR(x) (x)
#endif

#if !defined(printf_P)
#define printf_P printf
#endif

#if !defined(pgm_read_word)
#define pgm_read_word(p) (*(p))
#endif

#if !defined(pgm_read_byte)
#define pgm_read_byte(p) (*(p))
#endif

#if !defined(pgm_read_ptr)
#define pgm_read_ptr(p) (*(p))
#endif

class DummySpi {
public:
DummySpi(SPI_HandleTypeDef* hspi);
void begin();
uint8_t transfer(uint8_t data_to_send);
uint32_t get_baud();
private:
SPI_HandleTypeDef* _hspi;
};

#define RF24_SPI_PTR
#define _SPI DummySpi


#endif //RF24_UTILITY_STM32_RF24_ARCH_CONFIG_H
47 changes: 47 additions & 0 deletions utility/STM32/rf24_stm32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "RF24_arch_config.h"


static uint32_t rf24_get_time_us()
{
return 1000 * HAL_GetTick() + 1000 - (SysTick->VAL / (SystemCoreClock / 1000000));
}


void delayMicroseconds(uint32_t usecs)
{
uint32_t now = rf24_get_time_us();
uint32_t blocked_until = now + usecs;
while (blocked_until > rf24_get_time_us()) {}
}


DummySpi::DummySpi(SPI_HandleTypeDef *hspi) {
_hspi = hspi;
}


void DummySpi::begin() {
HAL_SPI_Init(_hspi);
}


uint8_t DummySpi::transfer(uint8_t data_to_send) {
const uint16_t size = 1;
uint8_t rx_data;
HAL_SPI_TransmitReceive(_hspi, &data_to_send, &rx_data, size, HAL_MAX_DELAY);
return rx_data;
}

uint32_t DummySpi::get_baud() {
// This method was tested with stm32f103c8t6. It may be different on other architectures
const uint8_t actual_config = _hspi->Init.BaudRatePrescaler;
uint16_t preescaler = 2;
if ((actual_config & SPI_CR1_BR_0) > 0)
preescaler = 2 * preescaler;
if ((actual_config & SPI_CR1_BR_1) > 0)
preescaler = 4 * preescaler;
if ((actual_config & SPI_CR1_BR_2) > 0)
preescaler = 16 * preescaler;
uint32_t baud = SystemCoreClock / preescaler;
return baud;
}

0 comments on commit 8656ba7

Please sign in to comment.