Перейти к содержанию
    

DMA UART выравнивание адреса по u16

Доброго времени суток.

UART работает в 9 битном режиме. Девятый бит мне как таковое не интересен, поэтому я его всегда отбрасываю и собираю данные в 8 битный буфер.

При запуске DMA на прием данных:

uint8_t Data[BUFFER_SIZE] = {0};
HAL_UART_Receive_DMA(BKI_UART, &Data[Index], BUFFER_SIZE);

В тех случаях когда Index нечетное значение, получаю HAL_ERROR

HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
       should be aligned on a u16 frontier, as data copy from RDR will be
       handled by DMA from a u16 frontier. */
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
    {
      if ((((uint32_t)pData) & 1U) != 0U)
      {
        return  HAL_ERROR;
      }
    }

Собственно вопрос, можно ли как то это обойти?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Какой МК? Откуда такая повальная привычка у многих не писать эту информацию..?
2. Почему в HAL_UART_Receive_DMA() передаете BUFFER_SIZE? Переполнение не возможно?
3. Ну Вам же прямо в функции комментарий дается - вроде, даже понятно почему так делать нельзя. Или нет?

Цитата

Собственно вопрос, можно ли как то это обойти?

С UART RDR в 9-битном режиме нужно оперировать в 16-битном доступе на чтение. Либо используйте 8-битный формат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) STM32G071

2) Размер буфера взят с большим запасом. В прерывании по простою вычисляю сколько данных пришло.

3) Я понимаю, что нельзя и почему. Но надеялся, что есть какого то рода обходные пути, чтоб как можно меньше исправлять уже в существующей программе. 

 

Как вариант нашел это: https://blog.ghmit.com.au/2019/09/stm32-9-bit-uart-halerror.html

Но пока разбираюсь и не совсем понимаю как это реализовать. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ваш МК умеет делать все автоматически (см. описание возможностей DMA-контроллера)
image.thumb.png.7f38775a7b7888c7b9e5d2df054e032b.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Arlleex, большое спасибо.

 //   if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
 //   {
 //     if ((((uint32_t)pData) & 1U) != 0U)
 //     {
 //       return  HAL_ERROR;
 //     }
 //   }

Решило всю проблему, МК и в самом деле автоматически подстраивается

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не это имел в виду... Я говорил о том, что DMA нужно настроить так, чтобы он читал из RDR UART-а 16-битными полусловами, затем обрезал старший байт, а младший помещал в указанный буфер памяти с инкрементом в 1 байт. Тогда Ваш ненужный 1 бит автоматически не попадал бы в приемный буфер. А что сейчас там в этом HAL_UART... мне не ведомо, и возможно, DMA работает криво, на самом деле лишь изображая "правильное" поведение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...