Например TDA7294

Форум РадиоКот • Просмотр темы - stm32f107 uart приемник + dma
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вт дек 30, 2025 01:39:53

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: stm32f107 uart приемник + dma
СообщениеДобавлено: Чт сен 04, 2014 10:12:47 
Вымогатель припоя
Аватар пользователя

Зарегистрирован: Ср фев 29, 2012 01:58:32
Сообщений: 672
Откуда: Харьков, Украина
Рейтинг сообщения: 0
Доброго всем времени суток!

Два дня бьюсь и не могу понять в чем причина данного поведения контроллера. Запустил dma + uart передатчик, все работает как надо. А для приемника возникает странный эффект. Идея следующая: инициализируется уарт, разрешается его прерывание. При срабатывании прерывания, читается байт (это длинна будущего сообщения), разрешается dma на прем этой длинны байт и запрещается прерывание от uart. Далее dma выгребает требуемое количество байт, генерирует свое прерывание. В этом прерывании отключается dma и разрешается прерывание uart. Все повторяется снова, первый пришедший байт и будет длинной будущего пакета. Первый раз все работает как надо. А дальше байт длинны попадает первым байтом в dma. Т.е., к примеру, отправляем 3, затем 1 2 3, вызывается прерывание dma, в памяти 1 2 3, но далее я отправляю 3 1 2 3 и после приема двойки вызывается прерывание dma, а в памяти 3 1 2 и так далее. Т.е. dma захватывает байт длинны всегда кроме первого запуска. Предполагаю, что что-то не так с остановкой dma, но что понять не могу. Помогите, плиз...

Инициализация uart:
Спойлер
Код:
void USART4_STM32F107RC_INIT(void)
{
   GPIO_InitTypeDef port;
   USART_InitTypeDef usart;
   
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
   
  GPIO_StructInit(&port);
  port.GPIO_Mode  = GPIO_Mode_AF_PP;
  port.GPIO_Pin   = usart4_tx;
  port.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(gpio_usart4, &port);
 
  port.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
  port.GPIO_Pin   = usart4_rx;
  port.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(gpio_usart4, &port);

  USART_StructInit(&usart);
  usart.USART_BaudRate = USART4_BAUDRATE;
  USART_Init(UART4, &usart);
      
   USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);

  USART_Cmd(UART4, ENABLE);

  NVIC_EnableIRQ(UART4_IRQn);
   
}

Прерывание uart:
Спойлер
Код:
void UART4_IRQHandler(void)
{
   uint16_t uart_len;
   if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
  {   
      USART_ClearITPendingBit(UART4, USART_IT_RXNE);
      uart_len = USART_ReceiveData(UART4);
      Set_UART4_Rx(uart_len);
  }
}

void Set_UART4_Rx(uint16_t uart_len)
{
   if (UART4_Rx_free)
   {
      NVIC_DisableIRQ(UART4_IRQn);
      DMA2_Rx_Init(uart_len);
   }
}

static void DMA2_Rx_Init(uint16_t length)
{
   DMA_InitTypeDef DMA_InitStructure;
   
   DMA_DeInit(DMA2_Channel3);
   
   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&UART4->DR);
   DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)UART4_Rx_buffer;
   DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;
   DMA_InitStructure.DMA_BufferSize         = length;
   DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
   DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
   DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
   DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
   DMA_InitStructure.DMA_Priority           = DMA_Priority_Low;
   DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
   DMA_Init(DMA2_Channel3, &DMA_InitStructure);
   
   USART_DMACmd(UART4, USART_DMAReq_Rx, ENABLE);
   
   DMA_ITConfig(DMA2_Channel3, DMA_IT_TC, ENABLE);
   
   NVIC_EnableIRQ(DMA2_Channel3_IRQn);
   
   DMA_Cmd(DMA2_Channel3, ENABLE);
   
   UART4_Rx_free = false;
}

Прерывание dma
Спойлер
Код:
void DMA2_Channel3_IRQHandler(void)
{
   if (DMA_GetITStatus(DMA2_IT_TC3) != RESET)
   {
      DMA_ClearITPendingBit(DMA2_IT_TC3);
      DMA_Cmd(DMA2_Channel3, DISABLE);
      
      USART_ClearITPendingBit(UART4, USART_IT_RXNE);
      NVIC_EnableIRQ(UART4_IRQn);
      
      UART4_Rx_free = true;
      
      
   }
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f107 uart приемник + dma
СообщениеДобавлено: Вт сен 09, 2014 11:10:54 
Вымогатель припоя
Аватар пользователя

Зарегистрирован: Ср фев 29, 2012 01:58:32
Сообщений: 672
Откуда: Харьков, Украина
Рейтинг сообщения: 0
Никто ничего не написал.

Поначалу тоже решил забить, но все же напишу. Может кому пригодится.
Кроме выключения дма, оказывается надо еще ее отключать от уарта, а то все равно уарт данные пихает в дма. Не совсем до конца понимаю как это происходит, в библиотечных функциях было рыться лень. Но эта строка лечит проблему
Код:
USART_DMACmd(UART4, USART_DMAReq_Rx, DISABLE);
:)) :tea:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f107 uart приемник + dma
СообщениеДобавлено: Вт сен 09, 2014 12:24:40 
Друг Кота

Карма: -18
Рейтинг сообщений: 29
Зарегистрирован: Вс дек 05, 2010 06:10:34
Сообщений: 4583
Откуда: ЮВ
Рейтинг сообщения: 0
Да... как частный случай может кому и сгодится... как панацея - нет...
Там довольно сложный механизм взаимодействия... поэтому дело даже не в библиотечных функциях... они не могут охватить всех нюансов периферии... Всё решается думалкой и логическим анализатором... ну и знанием железа...
Но вся эта сложность, как не странно, позволяет добиться удивительных результатов простыми методами...

_________________
"Я не даю готовых решений, я заставляю думать!"(С)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f107 uart приемник + dma
СообщениеДобавлено: Вт сен 09, 2014 14:14:34 
Вымогатель припоя
Аватар пользователя

Зарегистрирован: Ср фев 29, 2012 01:58:32
Сообщений: 672
Откуда: Харьков, Украина
Рейтинг сообщения: 0
Уважаемый HHIMERA. Я к тому, что как помигать светодиодиком или запустить шим советчиков много. Как только вопрос чуть посложнее... Тишина.

Человек когда идет на форум? Когда собственные мысли и идеи кончились. Когда полный голяк. Понятно, что если надо, то ты все равно разберешься. Вопрос в том, сколько времени ты потратишь. День, неделю или месяц? Никто же не ожидает готового решения проблемы. Имеется ожидание свежей идеи, новой мысли.


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: stm32f107 uart приемник + dma
СообщениеДобавлено: Вт сен 09, 2014 15:53:15 
Друг Кота

Карма: -18
Рейтинг сообщений: 29
Зарегистрирован: Вс дек 05, 2010 06:10:34
Сообщений: 4583
Откуда: ЮВ
Рейтинг сообщения: 0
eess9 писал(а):
Уважаемый HHIMERA. Я к тому, что как помигать светодиодиком или запустить шим советчиков много. Как только вопрос чуть посложнее... Тишина.

Уважаемый eess9... Это нормально... Именно поэтому я никогда не открываю тем и не задаю вопросов... проще самому разобраться... иногда такого насоветуют... Но по своему опыту... по завершению трансфера битами подключения ДМА никогда не рулил... разве что... только если нужна полная переконфигурация периферии...
Цитата:
Человек когда идет на форум? Когда собственные мысли и идеи кончились. Когда полный голяк. Понятно, что если надо, то ты все равно разберешься. Вопрос в том, сколько времени ты потратишь. День, неделю или месяц? Никто же не ожидает готового решения проблемы. Имеется ожидание свежей идеи, новой мысли.

Не спорю... но данный нюанс более смахивает на костыль... Обычно с такими вещами лучше разбираться до конца... во избежание...
SPL не юзаю... поэтому мысли и идеи иссякли незамедлительно...

_________________
"Я не даю готовых решений, я заставляю думать!"(С)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f107 uart приемник + dma
СообщениеДобавлено: Чт сен 11, 2014 00:04:58 
Вымогатель припоя
Аватар пользователя

Карма: 7
Рейтинг сообщений: 56
Зарегистрирован: Вт авг 28, 2012 22:21:33
Сообщений: 535
Рейтинг сообщения: 0
Кстати, вопрос. Что будет, если приемник включится во время передачи пакета? Поймает какой-нибудь байт из его середины? Допустим, со значением 200. Далее, он будет ждать 200 байт? Не переполнится ли буфер? Если пакеты небольшие - сколько он их сжуёт? Ладно, пусть жуёт, но где он остановится? Скорее всего в середине очередного пакета и следующим байтом длины опять будет ерунда? Вам бы, батенька, над организацией протокола подумать, а не DMA лепить куда ни попадя. Если я что-то не так понял и зря наезжаю извиняй конечно.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y