1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-20 06:45:16 +03:00

[H7] Apply HAL VCP TX fix

Apply changes equivalent to F7's fix:
VCP HAL transmit buffer fixes #7563

Further refactoring based on ledvinap's comments on #7563 is advised.
This commit is contained in:
jflyper 2019-02-11 23:40:43 +09:00
parent a8e9dd94e8
commit 43e1ee025b
2 changed files with 54 additions and 37 deletions

View file

@ -59,11 +59,16 @@
#include "usbd_cdc_interface.h"
#include "stdbool.h"
#include "drivers/nvic.h"
#include "build/atomic.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define APP_RX_DATA_SIZE 2048
#define APP_TX_DATA_SIZE 2048
#define APP_TX_BLOCK_SIZE 512
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
USBD_CDC_LineCodingTypeDef LineCoding =
@ -74,12 +79,12 @@ USBD_CDC_LineCodingTypeDef LineCoding =
0x08 /* nb. of bits 8*/
};
uint8_t UserRxBuffer[APP_RX_DATA_SIZE];/* Received Data over USB are stored in this buffer */
uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */
volatile uint8_t UserRxBuffer[APP_RX_DATA_SIZE];/* Received Data over USB are stored in this buffer */
volatile uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */
uint32_t BuffLength;
uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to
volatile uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to
start address when data are received over USART */
uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to
volatile uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to
start address when data are sent over USB */
uint32_t rxAvailable = 0;
@ -138,8 +143,8 @@ static int8_t CDC_Itf_Init(void)
}
/*##-5- Set Application Buffers ############################################*/
USBD_CDC_SetTxBuffer(&USBD_Device, UserTxBuffer, 0);
USBD_CDC_SetRxBuffer(&USBD_Device, UserRxBuffer);
USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t *)UserTxBuffer, 0);
USBD_CDC_SetRxBuffer(&USBD_Device, (uint8_t *)UserRxBuffer);
ctrlLineStateCb = NULL;
baudRateCb = NULL;
@ -244,33 +249,40 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance != TIMusb) return;
if (htim->Instance != TIMusb) {
return;
}
uint32_t buffptr;
uint32_t buffsize;
static uint32_t lastBuffsize = 0;
if (UserTxBufPtrOut != UserTxBufPtrIn)
{
if (UserTxBufPtrOut > UserTxBufPtrIn) /* Roll-back */
{
buffsize = APP_RX_DATA_SIZE - UserTxBufPtrOut;
}
else
{
buffsize = UserTxBufPtrIn - UserTxBufPtrOut;
}
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)USBD_Device.pCDC_ClassData;
buffptr = UserTxBufPtrOut;
USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t*)&UserTxBuffer[buffptr], buffsize);
if (USBD_CDC_TransmitPacket(&USBD_Device) == USBD_OK)
{
UserTxBufPtrOut += buffsize;
if (UserTxBufPtrOut == APP_TX_DATA_SIZE)
{
if (hcdc->TxState == 0) {
// endpoint has finished transmitting previous block
if (lastBuffsize) {
// move the ring buffer tail based on the previous succesful transmission
UserTxBufPtrOut += lastBuffsize;
if (UserTxBufPtrOut == APP_TX_DATA_SIZE) {
UserTxBufPtrOut = 0;
}
lastBuffsize = 0;
}
if (UserTxBufPtrOut != UserTxBufPtrIn) {
if (UserTxBufPtrOut > UserTxBufPtrIn) { /* Roll-back */
buffsize = APP_TX_DATA_SIZE - UserTxBufPtrOut;
} else {
buffsize = UserTxBufPtrIn - UserTxBufPtrOut;
}
if (buffsize > APP_TX_BLOCK_SIZE) {
buffsize = APP_TX_BLOCK_SIZE;
}
USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t*)&UserTxBuffer[UserTxBufPtrOut], buffsize);
if (USBD_CDC_TransmitPacket(&USBD_Device) == USBD_OK) {
lastBuffsize = buffsize;
}
}
}
}
@ -369,7 +381,13 @@ uint32_t CDC_Send_FreeBytes(void)
(APP_Rx_ptr_out > APP_Rx_ptr_in ? APP_Rx_ptr_out - APP_Rx_ptr_in : APP_RX_DATA_SIZE - APP_Rx_ptr_in + APP_Rx_ptr_in)
but without the impact of the condition check.
*/
return ((UserTxBufPtrOut - UserTxBufPtrIn) + (-((int)(UserTxBufPtrOut <= UserTxBufPtrIn)) & APP_TX_DATA_SIZE)) - 1;
uint32_t freeBytes;
ATOMIC_BLOCK(NVIC_BUILD_PRIORITY(6, 0)) {
freeBytes = ((UserTxBufPtrOut - UserTxBufPtrIn) + (-((int)(UserTxBufPtrOut <= UserTxBufPtrIn)) & APP_TX_DATA_SIZE)) - 1;
}
return freeBytes;
}
/**
@ -382,16 +400,15 @@ uint32_t CDC_Send_FreeBytes(void)
*/
uint32_t CDC_Send_DATA(const uint8_t *ptrBuffer, uint32_t sendLength)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)USBD_Device.pCDC_ClassData;
while (hcdc->TxState != 0);
for (uint32_t i = 0; i < sendLength; i++)
{
UserTxBuffer[UserTxBufPtrIn] = ptrBuffer[i];
UserTxBufPtrIn = (UserTxBufPtrIn + 1) % APP_TX_DATA_SIZE;
for (uint32_t i = 0; i < sendLength; i++) {
while (CDC_Send_FreeBytes() == 0) {
// block until there is free space in the ring buffer
delay(1);
}
ATOMIC_BLOCK(NVIC_BUILD_PRIORITY(6, 0)) { // Paranoia
UserTxBuffer[UserTxBufPtrIn] = ptrBuffer[i];
UserTxBufPtrIn = (UserTxBufPtrIn + 1) % APP_TX_DATA_SIZE;
}
}
return sendLength;
}

View file

@ -65,7 +65,7 @@
/* Periodically, the state of the buffer "UserTxBuffer" is checked.
The period depends on CDC_POLLING_INTERVAL */
#define CDC_POLLING_INTERVAL 10 /* in ms. The max is 65 and the min is 1 */
#define CDC_POLLING_INTERVAL 5 /* in ms. The max is 65 and the min is 1 */
/* Exported typef ------------------------------------------------------------*/
/* The following structures groups all needed parameters to be configured for the