USART + DMA отправляет неверное количество байтов (STM32F407VGT6, RS485) - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь перенести проект из HAL в LL.Я использую USART1 + DMA2 (RS485).Прием в порядке, но передача отсутствует.

Например, буфер передачи начинается с {1, 2, 3, 4}.

  • Когда я устанавливаю длину данных DMA равной 1, ничего не происходитотправлено
  • Когда я устанавливаю длину данных в 2, отправляется {0xFF}
  • Когда я устанавливаю длину данных в 3, отправляется {0x01, 0xFF}
  • Когда я устанавливаюдлина данных до 4, отправляется {0x01, 0x02, 0xFF}

«Отправлено» означает то, что я вижу в мониторе портов на моем ПК.Таким образом, данные не повреждены, просто неполны.

Я пытался включить / отключить прерывания, очистить флаги.Также я попытался получить те же регистры DMA и UART в LL, что и в HAL.Пока безуспешно.

...
typedef uint8_t   uiRX_t;
typedef uint8_t   uiTX_t;

#define TX_BUFF_LEN   320
#define RX_BUFF_LEN   1

typedef struct {
  uint16_t  tx_len;
  uiTX_t    tx_buff[ TX_BUFF_LEN ];
  uiRX_t    rx_buff[ RX_BUFF_LEN ];
} DataStorage;
...
volatile  DataStorage  data = { 0 };

...

int main()
{
  ...
  while ( 1 ) {
    while ( LL_DMA_IsEnabledStream( USART_DMA, USART_DMA_STREAM_TX ) ) { }

    LL_DMA_SetDataLength( USART_DMA, USART_DMA_STREAM_TX, data.tx_len );
    LL_GPIO_SetOutputPin( USART_PORT, USART_PIN_DE );
    LL_DMA_EnableStream( USART_DMA, USART_DMA_STREAM_TX );

    LL_mDelay( SYSTICKS_FREQ );
  }
}

...

void  init_sys( void ) {
  ...
  LL_APB2_GRP1_EnableClock( LL_APB2_GRP1_PERIPH_SYSCFG );
  LL_APB1_GRP1_EnableClock( LL_APB1_GRP1_PERIPH_PWR );
  LL_PWR_SetRegulVoltageScaling( LL_PWR_REGU_VOLTAGE_SCALE1 );

  NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_3 );

  LL_UTILS_PLLInitTypeDef   pll = {
                              .PLLM = LL_RCC_PLLM_DIV_16,
                              .PLLN = 336,
                              .PLLP = LL_RCC_PLLP_DIV_2
                            };

  LL_UTILS_ClkInitTypeDef   clk = {
                              .AHBCLKDivider  = LL_RCC_SYSCLK_DIV_1,
                              .APB1CLKDivider = LL_RCC_APB1_DIV_4,
                              .APB2CLKDivider = LL_RCC_APB2_DIV_2
                            };

  if( SUCCESS != LL_PLL_ConfigSystemClock_HSI( &pll, &clk ) ) {
    Error_Handler();
  }

  LL_SYSTICK_SetClkSource( LL_SYSTICK_CLKSOURCE_HCLK );
  LL_InitTick( SystemCoreClock, SYSTICKS_FREQ );
  LL_SYSTICK_EnableIT();
}

...

void init_nvic( const IRQn_Type irq, const uint32_t priority0, const uint32_t priority1 ) {
  NVIC_SetPriority( irq, NVIC_EncodePriority( NVIC_GetPriorityGrouping(), priority0, priority1 ) );
  NVIC_EnableIRQ( irq );
}

...

void  init_dma() {
  LL_AHB1_GRP1_EnableClock( USART_DMA_PERIPH );

  init_nvic( USART_DMA_TX_IRQn, 1, 0 );

  LL_DMA_SetChannelSelection( USART_DMA, USART_DMA_STREAM_TX, USART_DMA_CHANNEL_TX );

  LL_DMA_ConfigTransfer( USART_DMA, USART_DMA_STREAM_TX,
                        LL_DMA_DIRECTION_MEMORY_TO_PERIPH |
                        LL_DMA_MODE_NORMAL                |
                        LL_DMA_PERIPH_NOINCREMENT         |
                        LL_DMA_MEMORY_INCREMENT           |
                        LL_DMA_PDATAALIGN_BYTE            |
                        LL_DMA_MDATAALIGN_BYTE            |
                        LL_DMA_PRIORITY_HIGH );

  LL_DMA_DisableFifoMode( USART_DMA, USART_DMA_STREAM_TX );

  LL_DMA_ConfigAddresses( USART_DMA, USART_DMA_STREAM_TX,
                         ( ( uint32_t ) data.tx_buff ),
                         LL_USART_DMA_GetRegAddr( USART_N ),
                         LL_DMA_GetDataTransferDirection( USART_DMA, USART_DMA_STREAM_TX ) );

  LL_DMA_EnableIT_TC( USART_DMA, USART_DMA_STREAM_TX );
  LL_DMA_EnableIT_TE( USART_DMA, USART_DMA_STREAM_TX );
}

...

void  DMA_TransmitComplete_Callback( void )
{
  LL_GPIO_ResetOutputPin( USART_PORT, USART_PIN_DE );
  LL_DMA_DisableStream( USART_DMA, USART_DMA_STREAM_TX );
}

void  DMA_TransferError_Callback( void )
{
  LL_DMA_DisableStream( USART_DMA, USART_DMA_STREAM_TX );
}

Возможно, было бы лучше предоставить полные файлы, так как они короткие, но ТАК не рекомендует.Полный проект можно найти здесь

...