8 years ago.

Fast I/O with STM32F103RB

Hello everybody,

please excuse my bad english, I'm a native speaking german. Because of interfacing hardware (shift registers and counters) using bit banging and a STM32F103RB I need to have faster I/O operations than the "DigitalOut".

With Nucleo Board Nucleo-F401RE Board there is no problem to use the library "FastIO". Is there any existing port to F103 or is there an other solution to something quicker than DigitalOut ?

Nice regards,

Ralph

Ralph - try the $15 USD kit from XMOS (startKit). This CPU can really bit bang fast using a free C compiler. On this note, take care to not to be too fast with the XMOS CPU (can clock out at 100 Mhz if required).

http://www.digikey.com/product-search/en?keywords=xmos%20startkit

Caution: XMOS is not MBED enabled. It may make sense to interface your mbed board to the XMOS using SPI or similar. To start with, test the XMOS board as-is with your external digital I/O -> then marry with a mbed board if necessary.

posted by Sanjiv Bhatia 07 Apr 2016

3 Answers

8 years ago.

I dont know your hardware setup, but if you need to send data to a shiftregister like the 74595 or similar you can use the SPI port and transfer the data in chunks of 8 bits or more. SPI can also be used with DMA so that would need very little CPU overhead. Obviously bitbanging/fastio gives you maximum control over the waveforms, but at the expense of speed and probably timing accuracy.

Accepted Answer

I am using SPI but the switching the chipselect signals to the shiftregisters (4094) is to slow.. :-((

posted by Ralph Seelig 07 Apr 2016
8 years ago.

As far as I am aware there is no alternative library (but then again I don't know every library around here, I wanted to track such stuff in the cookbook, but mbed staff decided to freeze the cookbook).

Option A: Check if you remove the #ifdef for each of the existing two STM implementations if it works. Maybe they are sufficiently similar.

Option B: If that does not work, see if with the reference manual you can program it yourself

Option C: Send me an F103 and I do it for you :P. (I don't have it myself, so unless it is really exactly the same only they changed some names, I simply can't do it without a board).

Smile, I can send you a STM32F103C8 (it runs quiet well under mbed) ... :-))

posted by Ralph Seelig 06 Apr 2016

Let's use e-mail :)

posted by Erik - 06 Apr 2016

Hello Erik,

Thank you for the great FastIO library. Below is my humble attempt to contribute for the NUCLEO-F103RB boards. I did not have chance to perform thorough tests but the basic bench results are attached.
Zoltan

FastIO_NUCLEO-F103RB.h

#if defined(TARGET_STM32F103RB)

#include "mbed.h"
#include "pinmap.h"

typedef struct {
    uint32_t mask;
} fastio_vars;

#define PINMASK             (1 << STM_PIN(pin))
#define PORT                ((GPIO_TypeDef*)(GPIOA_BASE + 0x0400 * STM_PORT(pin)))

#define PIN_FUNCTION_GPIOMODE(gpiomode) \
    uint32_t pull = PullNone; \
    __IO uint32_t* gpio_reg_hl; \
    uint32_t shift; \
    \
    if (STM_PIN(pin) < 8) { \
        shift = (STM_PIN(pin) * 4); \
        gpio_reg_hl = &(PORT->CRL); \
    } else { \
        shift = (STM_PIN(pin) % 8) * 4; \
        gpio_reg_hl = &(PORT->CRH); \
    } \
    \
    if ((!(*gpio_reg_hl & (0x03 << shift))) \
        && (!!(*gpio_reg_hl & (0x08 << shift))) \
        && (!(*gpio_reg_hl & (0x04 << shift)))) { \
        if (!!(PORT->ODR & (0x01 << STM_PIN(pin)))) { \
            pull = PullUp; \
        } else { \
            pull = PullDown; \
        } \
    } else { \
        if (!!(*gpio_reg_hl & (0x04 << shift))) { \
            pull = OpenDrain; \
        } \
    } \
    \
    pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); 

#define SET_DIR_INPUT       PIN_FUNCTION_GPIOMODE(0)
#define SET_DIR_OUTPUT      PIN_FUNCTION_GPIOMODE(1)
#define INIT_PIN            pin_function(pin, GPIO_MODE_INPUT); container.mask = PINMASK
#define DESTROY_PIN
#define SET_MODE(pull)      pin_mode(pin, pull);
#define WRITE_PIN_SET       (PORT->BSRR = PINMASK)
#define WRITE_PIN_CLR       (PORT->BSRR = (PINMASK << 16))
#define READ_PIN            ((PORT->IDR & container.mask) ? 1 : 0)

#endif


Test bench result:

Starting test bench
Verifying basic behavior
Basic behavior verified

Measuring fixed write pattern speed
Standard took 18.03 cycles, FastIO took 3.75 cycles, which is 21%
Standard took 250ns, FastIO took 52ns

Measuring variable write pattern speed
Standard took 22.03 cycles, FastIO took 12.54 cycles, which is 57%
Standard took 306ns, FastIO took 174ns

Measuring read speed
Standard took 21.05 cycles, FastIO took 10.02 cycles, which is 48%
Standard took 292ns, FastIO took 139ns

Measuring toggling using operators speed
Standard took 41.09 cycles, FastIO took 9.51 cycles, which is 23%
Standard took 571ns, FastIO took 132ns

Measuring switching between input and output
Standard took 692.61 cycles, FastIO took 594.35 cycles, which is 86%
Standard took 9620ns, FastIO took 8255ns

posted by Zoltan Hudak 04 Feb 2017
8 years ago.

May be this datasheet can help you: http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/CD00161566.pdf

I'm studying this datasheet a long time, but I'm not able to port to mbed. In this moment I try to insert a editor/make minimalistic blink program to mbed ...

posted by Ralph Seelig 06 Apr 2016

The datasheet specs the device characteristics. You need the reference manual to see how to address the peripherals.

posted by Erik - 06 Apr 2016