2014-11-24 12:06 PM
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_HIGHis there anything I can do or example I could follow or inspire myself? (beside implementing some asm?)thanxMart #bitband-bit-bang2014-11-24 07:40 PM
Architecturally BSRR is a 32-bit register
The assignment would permitted a rotate, harder to do in C Remember the interactions with the APB/AHB will be less efficient than operations on processor registers, and that peripheral registers are ''volatile'' and will be re-read, often unnecessarily with compound modification. Consider loading settings into a temporary register, and modify that before storing the finished value back.2014-11-24 11:38 PM
why doesnt stm32cube have any usb samples for stm32f4-discovery? there is a FS USB port on
2014-11-24 11:45 PM
The barrel shift in ARM is ''free'', i.e. rotation can be added to any instruction without timing penalty. Thumb(2) places restrictions on this, but still rotation is quite effective.
This: void foo(uint8_t a) __attribute__((noinline)); void foo(uint8_t a) { uint32_t t; t = a & 0x0F; t = (t >> 2) | (t << (32 - 2)); // ROR 2 t = t | ((t >> 16) | (t << (32 - 16))); // + ROR 16 GPIOD->BSRR = t; // this needs augmented stm32f4xx.h } compiles in gcc into 800019c: f000 000f and.w r0, r0, #15 80001a0: f44f 6340 mov.w r3, #3072 ; 0xc00 80001a4: ea4f 00b0 mov.w r0, r0, ror #2 80001a8: f2c4 0302 movt r3, #16386 ; 0x4002 80001ac: ea40 4030 orr.w r0, r0, r0, ror #16 80001b0: 6198 str r0, [r3, #24] 80001b2: 4770 bx lr which runs in 9 cycles including the ''call'' and ''ret''; and much of the time is consumed to load the register address which in real program would often get optimized for multiple accesses to the same peripheral. JW2014-11-24 11:47 PM
> why doesnt stm32cube have any usb samples for stm32f4-discovery? there is a FS USB port
on 1. don't hijack other threads, start your own 2. don't start it in this forum as it is a cube-related question - rather, start it in the dedicated [DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Java/AllItems.aspx]''software tools'' subforum2014-11-24 11:58 PM
2014-11-25 07:37 AM
if you read my posts, i started but nobody answer to me. but i will start again
Forums depend on others to answer the posts, if no one present has an answer, it will be left unanswered.2014-11-27 07:14 AM
Hi,
I understand what Clive1 said about ''design ahead of time''. If all ports were aligned, it will be easy to write directly in the GPIOX->BSSR register. Now, according to the current state, if I have the value 0x6 to transmit:Port D0 1 1 0PIN_1 PIN_0 PIN_15 PIN_14I dont see how can I can do it with doing a stupid HAL_GPIO_WritePin for each like I am doing in order to save some cycle and improve performance...Mart2014-11-27 08:00 AM
> 0 1 1 0
> PIN_1 PIN_0 PIN_15 PIN_14
> > I dont see how can I can do it with doing a stupid HAL_GPIO_WritePin for each like I am > doing in order to save some cycle and improve performance... But why would you use HAL_GPIO_WritePin(), once it's stupid? I gave you the solution above, what is in it that is not clear? JW2014-12-01 11:35 AM
Hi Mr. waclawek,
obviously, I dont understand the mechanic behind it.However, testing the provided function, I ended up with a value of of 0x80018001 in ''t''. However, using HAL_GPIO_WritePin, I have 0x00008001 in the GPIOD->ODR register which is correct:input: 0x46Port E0 1 0 0PIN_7 PIN_8 PIN_9 PIN_10Port D
0 1 1 0
PIN_1 PIN_0 PIN_15 PIN_14
Mart2014-12-01 11:47 AM
I made a mistake:
input: 0x46
Port E
0 1 0 0
PIN_10 PIN_9 PIN_8 PIN_7
Port D
0 1 1 0
PIN_1 PIN_0 PIN_15 PIN_14