cancel
Showing results for 
Search instead for 
Did you mean: 

Improve bitbang driver speed

martingingras9
Associate II
Posted on November 24, 2014 at 21:06

Hi,

I am using the STM32F2xx cube API to implement a raw bitbang usb driver for the FTDI ft245.  I am currently achieving speed of 5000 bytes/s.  I would like to improve the speed.  The bitbang code is simple as:

<..>

__disable_irq();

// set data pins      

        HAL_GPIO_WritePin(FT_D0_PORT, FT_D0_PIN, (CHECK_BIT(data, 0) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

        HAL_GPIO_WritePin(FT_D1_PORT, FT_D1_PIN, (CHECK_BIT(data, 1) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

        HAL_GPIO_WritePin(FT_D2_PORT, FT_D2_PIN, (CHECK_BIT(data, 2) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

        HAL_GPIO_WritePin(FT_D3_PORT, FT_D3_PIN, (CHECK_BIT(data, 3) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

        HAL_GPIO_WritePin(FT_D4_PORT, FT_D4_PIN, (CHECK_BIT(data, 4) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

        HAL_GPIO_WritePin(FT_D5_PORT, FT_D5_PIN, (CHECK_BIT(data, 5) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

        HAL_GPIO_WritePin(FT_D6_PORT, FT_D6_PIN, (CHECK_BIT(data, 6) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

        HAL_GPIO_WritePin(FT_D7_PORT, FT_D7_PIN, (CHECK_BIT(data, 7) == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);

__enable_irq();

<...>

The pins are configured as follow:

FT_DX_PORT, FT_DX_PIN, GPIO_MODE_INPUT, GPIO_NOPULL, GPIO_SPEED_HIGH

is there anything I can do or example I could follow or inspire myself? (beside implementing some asm?)

thanx

Mart

#bitband-bit-bang
20 REPLIES 20
Posted on November 24, 2014 at 21:31

Is there any rational relationship between the data bits, and the GPIO pins/banks? This is where it helps to think about the design ahead of time, rather than randomly assign available pins.

For multiple contiguous bits you could shift and mask them onto the GPIO(s) ODR
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
martingingras9
Associate II
Posted on November 24, 2014 at 22:55

Hi Clive1,

>Is there any rational relationship between the data bits, and the GPIO pins/banks?

not quite sure of you meant here. I am a bit confused.

>  GPIO(s) ODR

GPIO port output data register? I will be reading about those registers.  Is there any example I should take a look at?

thanx

Mart

jpeacock
Associate III
Posted on November 24, 2014 at 23:00

You might consider going to Bitband addressing for the pins, bypass the libraries, and set/reset the bits directly (but no RMW, not always reliable on I/O pins).  For data being serialized do the same thing, convert the data addresses into pointers to large bit arrays with BitBand.  It will save you the time on logical operations for particular bits and calculating pointers and bit masks.

  Jack Peacock
Posted on November 24, 2014 at 23:18

>Is there any rational relationship between the data bits, and the GPIO pins/banks?

 

 

not quite sure of you meant here. I am a bit confused.

Rational -> D0 = PE0, D1 = PE1, .. D7 = PE7

Irrational -> D0 = PB7, D1 = PA4, D2 = PC3, D3 = PC2, ...

Multiple bits can be altered doing an RMW action on GPIOx->ODR, or more swiftly GPIOx->BSRR
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
martingingras9
Associate II
Posted on November 25, 2014 at 01:30

Hi Clive1,

ok I understand.   I need to group the action by Port using ODR directly to save some time.

thanx

Mart

martingingras9
Associate II
Posted on November 25, 2014 at 02:38

something like that?:

 // GPIOD -> FT_D0_PIN, FT_D1_PIN, FT_D2_PIN, FT_D3_PIN

        // GPIOE -> FT_D4_PIN, FT_D5_PIN, FT_D6_PIN, FT_D7_PIN

        GPIOD->ODR = data & 0x0F;

        GPIOE->ODR = data & 0xF0;

Posted on November 25, 2014 at 02:53

GPIOD->ODR = (GPIOD->ODR & 0xFFF0) | (data & 0x0F); // PD0,1,2,3

GPIOE->ODR = (GPIOE->ODR & 0xFF0F) | (data & 0xF0); // PE4,5,6,7

GPIOD->BSSR = (data & 0x0F) | ((~data & 0x0F) << 16);

GPIOE->BSSR = (data & 0xF0) | ((~data & 0xF0) << 16);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
martingingras9
Associate II
Posted on November 25, 2014 at 03:19

Hi,

I will need some time to digest that.  BSRR is split in BSRRL and BSRRH apparently.

thnx

Mart

martingingras9
Associate II
Posted on November 25, 2014 at 03:26

in fact:

#define FT_D0_PORT     GPIOD

#define FT_D0_PIN      GPIO_PIN_14

#define FT_D1_PORT     GPIOD

#define FT_D1_PIN      GPIO_PIN_15

#define FT_D2_PORT     GPIOD

#define FT_D2_PIN      GPIO_PIN_0

#define FT_D3_PORT     GPIOD

#define FT_D3_PIN      GPIO_PIN_1

so uhm