Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: UART в SAM7X: Tx+PDC
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
athlon64
Здравствуйте
Для отправки в порт фрейма необходимо использовать DMA, используя стандартный пример от атмела удалось добиться вывода с использованием DMA. Только вот неясно как поймать момент окончания отправки чтобы уничтожить временный буфер отправки.
В даташите сказано что для этой цели можно использовать биты TXBUFE и ENDTX в статусном регистре UART, по выставлению которых можно генерировать прерывание. Добавил в обработчик проверку этих битов и в инициализацию портов добавил включение прерывания по US_ENDTX.
Так вот, если прерывание по US_ENDTX или US_TXEMPTY включено то процессор зависает при первой же передаче, как будто забыл сбросить какой то бит в обработчике прерывания от UART.

Код инициализации:
Код
  unsigned int iBaud = 9600;
  PIO_Configure(USART1_pins, PIO_LISTSIZE(USART1_pins));
  PMC_EnablePeripheral(AT91C_ID_US1);                           // Enable the peripheral clock in the PMC
  USART_Configure(AT91C_BASE_US1, mode, iBaud, 48000000);       // Устанавливаем режим и скорость порта
  IRQ_ConfigureIT(AT91C_ID_US1, 5, IRQ_UART1_RX);               // IRQ_UART1_RX - обработчик прерывания по приходу байта // или по таймауту
  IRQ_EnableIT(AT91C_ID_US1);                                   // Разрешаем прерывание от UART1
  USART_SetTransmitterEnabled(AT91C_BASE_US1, 1);               // Включаем передатчик
  USART_SetReceiverEnabled(AT91C_BASE_US1, 1);                  // Включаем приёмник

  AT91C_BASE_US1->US_IER = AT91C_US_RXRDY | AT91C_US_TIMEOUT | AT91C_US_ENDTX;  // Так зависает  
//  AT91C_BASE_US1->US_IER = AT91C_US_RXRDY | AT91C_US_TIMEOUT;  // А так - нет
  AT91C_BASE_US1->US_RTOR=cstTimeCOM;                           // Устанавливаем тайм-аут


Обработчик прерывания:
Код
void IRQ_UART1_RX()
{
  unsigned int status = AT91C_BASE_US1->US_CSR & AT91C_BASE_US1->US_IMR;

  if (status & AT91C_US_ENDTX)     // Передача закончена
  {
// Вот это событие хочу поймать
  }
  
  if (status & AT91C_US_OVRE)     // Буфер был переполнен
    SizeCOM1 = 0;

  if (status & AT91C_US_RXRDY)    // если прерывание произошло по приёму 1 байт буфера
    InBufCOM1[SizeCOM1++] = AT91C_BASE_US1->US_RHR; // Заполнение буфера порта COM1
  
  if (status & AT91C_US_TIMEOUT)  // если прерывание произошло по таймауту, фрейм окончен
  {
    AT91C_BASE_US1->US_CR = AT91C_US_STTTO;                            // Сбрасываем тайм-аут
// Обработка пакета
    }
  }
}
aaarrr
В вашем случае прерывание ENDTX нужно разрешать после начала передачи и запрещать непосредственно в обработчике после получения.
RabidRabbit
Цитата(athlon64 @ Mar 29 2011, 16:47) *
А что-то в инициализации не видно настроки буфера PDC. Без такой настройки флажок ENDTX будет, по идее, всё время взведён, и процессор безвылазно будет сидеть в обработчике прерывания... То есть, для передачи надо настроить PDC, после прерывания (как указал aaarrr), запретить прерывание по ENDTX.
Упс, тут уже ответили...
athlon64
Помогло, громадное спасибо за подсказку yeah.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.