mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 22:35:23 +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:
parent
a8e9dd94e8
commit
43e1ee025b
2 changed files with 54 additions and 37 deletions
|
@ -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,32 +249,39 @@ 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;
|
||||
|
||||
uint32_t buffptr;
|
||||
uint32_t buffsize;
|
||||
|
||||
if (UserTxBufPtrOut != UserTxBufPtrIn)
|
||||
{
|
||||
if (UserTxBufPtrOut > UserTxBufPtrIn) /* Roll-back */
|
||||
{
|
||||
buffsize = APP_RX_DATA_SIZE - UserTxBufPtrOut;
|
||||
if (htim->Instance != TIMusb) {
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
uint32_t buffsize;
|
||||
static uint32_t lastBuffsize = 0;
|
||||
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)USBD_Device.pCDC_ClassData;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
buffptr = UserTxBufPtrOut;
|
||||
USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t*)&UserTxBuffer[UserTxBufPtrOut], buffsize);
|
||||
|
||||
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)
|
||||
{
|
||||
UserTxBufPtrOut = 0;
|
||||
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,15 +400,14 @@ 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++)
|
||||
{
|
||||
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;
|
||||
while (CDC_Send_FreeBytes() == 0) {
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
return sendLength;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue