UARTs RTL00

pvvx

Активный участник сообщества
На модуле RTL00 c RTL8710AF доступны все UART:

LOG_UART
, UART0, UART1, UART2.

Единственное, что у UART1 выводится на внешние ноги только TX [PE_4] (RTS/CTS/RX - в такой конфигурации нет: PE_5/PE_6/PE_5).
--------
Кто знает как получить прерывание по концу передаче символа(ов) ?
По пустому TX FIFO прерывание не годится - оно возникает при начале передаче последнего символа.
Использовать LOOPBACK и прерывание RX? :
Код:
#define RUART_MCR_LOOPBACK                BIT4    //*BIT4, LoopBack Bit (LOOPBACK)
HAL_RUART_WRITE32(sobj.hal_uart_adp.UartIndex, RUART_MODEM_CTL_REG_OFF, HAL_RUART_READ32(sobj.hal_uart_adp.UartIndex, RUART_MODEM_CTL_REG_OFF) | BIT4);
Так-же есть вопросы по прерыванию EDSSI, Enable Modem Status Interrupt - когда оно возникает?


PS: Описание UART частично сходится (первые регистры, без коррекции скорости) с UART у "Intel® Quark™ microcontroller D2000"
 
Последнее редактирование:

pvvx

Активный участник сообщества
Такие вот странности в SDK с UART:
RTL00_UART.gif
При не заполнении RX FIFO вылезает задержка до вызова uart_irq() после последнего принятого символа, равная длительности 4-х символов. При заполнении RX FIFO - сразу вызывается uart_irq(). Где устанавливается данная задержка - неизвестно. Принимать по одному символу на прерывание как-то не-то (можно задать serial_rx_fifo_level(&sobj, FifoLv1Byte), а для TX - никак, если по хамски не лезть в регистры :) ).
Вторая пакость - после передачи вызывается 2 раза uart_irq(id, TxIrq). С чего такое - ?
Код:
/* Пример rx-tx  UART2 */
#include "device.h"
#include "serial_api.h"
#include "serial_ex_api.h"
#include "diag.h"

#define UART_TX   PA_4
#define UART_RX   PA_0
#define UART_CTS  PA_1
#define UART_RTS  PA_2

#define PIN_OUT1  PA_5
#define PIN_OUT2  PC_4
gpio_t gpio_out1;
gpio_t gpio_out2;
void uart_irq(uint32_t id, SerialIrq event)
{
    serial_t    *sobj = (void*)id;

    if(event == RxIrq) {
        gpio_write(&gpio_out2, 0);
        gpio_write(&gpio_out2, 1);
        while(serial_readable(sobj))
            serial_putc(sobj, serial_getc(sobj));
    }

    if(event == TxIrq) {
        gpio_write(&gpio_out1, 0);
        gpio_write(&gpio_out1, 1);
    }
}
void main(void)
{
    serial_t    sobj;
    int ret;
    int i=0;
    int len;
    u32 x;

    ConfigDebugErr = ~_DBG_GDMA_;
//    ConfigDebugInfo = ~_DBG_GDMA_;
    ConfigDebugWarn = ~_DBG_GDMA_;

    gpio_init(&gpio_out1, PIN_OUT1);
    gpio_dir(&gpio_out1, PIN_OUTPUT);    // Direction: Output
    gpio_mode(&gpio_out1, PullNone);     // No pull
    gpio_write(&gpio_out1, 1);
    gpio_init(&gpio_out2, PIN_OUT2);
    gpio_dir(&gpio_out2, PIN_OUTPUT);    // Direction: Output
    gpio_mode(&gpio_out2, PullNone);     // No pull
    gpio_write(&gpio_out2, 1);

    serial_init(&sobj, UART_TX,UART_RX);
    serial_baud(&sobj, 38400);
    serial_format(&sobj, 8, ParityNone, 1);
    serial_irq_handler(&sobj, uart_irq, (uint32_t)&sobj);
    serial_irq_set(&sobj, RxIrq, 1);
    serial_irq_set(&sobj, TxIrq, 1);

    HalRuartDumpRegRtl8195a(&sobj.hal_uart_adp);
    while (1);
}
Третья пакость - при вызове всяких serial_send_stream() прерывание uart_irq(id, TxIrq) не вызывается.

Итого - все, что связано с UART в SDK - в помойку?
Неудивительно, что пример, описанный в AN0046 Realtek Ameba uart adapter.pdf, не работает - виснет при выводе в UART :)

PS: HalRuartDumpRegRtl8195a() имеет ошибку - просто глухо виснет :)
Код:
VOID
HalRuartDumpRegRtl8195a(
    IN VOID *Data
)
{
    PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data;
    u8 UartIndex;
    u32 i;
    u32 RegValue;

    UartIndex = pHalRuartAdapter->UartIndex;
    /* Set DLAB bit to 1 to access DLL/DLM */
    RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF);
    RegValue |= RUART_LINE_CTL_REG_DLAB_ENABLE;
    HAL_RUART_WRITE32(UartIndex, RUART_LINE_CTL_REG_OFF, RegValue);
   
    for (i=0;i<0x40;i+=4) {
        DBG_8195A("UART Reg[0x%x] = 0x%x\r\n", i, HAL_RUART_READ32(UartIndex, i));
    }
   
/* clear DLAB bit */
    RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF);
    RegValue &= ~(RUART_LINE_CTL_REG_DLAB_ENABLE);
    HAL_RUART_WRITE32(UartIndex, RUART_LINE_CTL_REG_OFF, RegValue);
}
 

Вложения

Последнее редактирование:

sharikov

Active member
Такие вот странности в SDK с UART:
При не заполнении RX FIFO вылезает задержка до вызова uart_irq() после последнего принятого символа, равная длительности 4-х символов. При заполнении RX FIFO - сразу вызывается uart_irq(). Где устанавливается данная задержка - неизвестно.
прверьте флаги Interrupt Identification вдруг они равны 1100 = character timeout.

A FIFO timeout interrupt will occur if all the following conditions exist:
a. There is at least one character in the FIFO
b. The most recent serial character received was longer than four continuous character times ago (one
character is eight data bits, one start bit, one parity bit and two stop bits)
c. The most recent CPU read of the FIFO was longer than four continuous character times ago.
d. When a timeout interrupt has occurred, the FIFO is cleared. The timer resets when the CPU reads one
character from the RCVR FIFO.



По передаче непонятно.

UPD:
В Interrupt Enable есть 2 бита: ETBEI, Enable Transmit Holding Register Empty Interrupt и PTIME, Programmable THRE Interrupt Mode Enable. Если оба разрешены возможно по окончании передачи будет 2 прерывания: по опустошению регистра и фифо.
 
Последнее редактирование:

pvvx

Активный участник сообщества
По передаче непонятно.

UPD:
В Interrupt Enable есть 2 бита: ETBEI, Enable Transmit Holding Register Empty Interrupt и PTIME, Programmable THRE Interrupt Mode Enable. Если оба разрешены возможно по окончании передачи будет 2 прерывания: по опустошению регистра и фифо.
Если будет прерывание по пустому фифо, то оно должно быть бесконечным, пока не снято? Или там защелка - один раз при переходе через кол-во в fifo?

Это 'four continuous character times ago (one character is eight data bits, one start bit, one parity bit and two stop bits)' неизменяемо?
PS: выдрано из UART16550Transceiver-Documentation.PDF ?
Есть ещё типа тут, нечто похожее: 16550 registers
 
Последнее редактирование:

sharikov

Active member
Если будет прерывание по пустому фифо, то оно должно быть бесконечным, пока не снято? Или там защелка - один раз при переходе через кол-во в fifo?
Сброс по разному в зависимости от типа прерывания в IIR. Здесь есть таблица.
Прерывания имеют несколько приоритетов (3 или 4 в разных реализациях), в IIR отображается прерывание с высшим приоритетом, остальные ожидают.
Приоритеты начиная с высшего: Receiver Line Status, Received Data Ready, Transmitter Holding Register Empty and Modem Status.
А вот другой вариант приоритетов (lpc17xxuser_manual):
Приоритет - Флаг прерывания
Highest - RX Line Status/Error
Second - RX Data Available
Second - Character Time-out indication
Third - THRE

Это 'four continuous character times ago (one character is eight data bits, one start bit, one parity bit and two stop bits)' неизменяемо?
В стандартной реализации 16550 неизменяемо.

PS: выдрано из UART16550Transceiver-Documentation.PDF ?
Да.
 

pvvx

Активный участник сообщества
Сброс по разному в зависимости от типа прерывания в IIR. Здесь есть таблица.
Прерывания имеют несколько приоритетов (3 или 4 в разных реализациях), в IIR отображается прерывание с высшим приоритетом, остальные ожидают.
Приоритеты начиная с высшего: Receiver Line Status, Received Data Ready, Transmitter Holding Register Empty and Modem Status.
А вот другой вариант приоритетов (lpc17xxuser_manual):
Приоритет - Флаг прерывания
Highest - RX Line Status/Error
Second - RX Data Available
Second - Character Time-out indication
Third - THRE
Это всё ясно, но был тест SDK, а там .... :)
В SDK нет ясности, от куда вызывается uart_irq(), назначенный через serial_irq_set(). Среда то RTOS... и рассматривать там регистры UART возможно уже бесполезно.
Сейчас основная задача слепить на этой UART RS-485 Modbus, т.е. получить сигналы RX-TX-DE и желательно вызовы по irg с временными характеристиками modbus. А в RTL8710 без 'раскопок' минимальный шаг таймера (тик RTOS) к 1 ms.
Т.е. придется лепить полностью свой драйвер, там и погляжу все флаги и т.д.
 
Последнее редактирование:

sharikov

Active member
Это всё ясно, но был тест SDK, а там .... :)
В SDK нет ясности, от куда вызывается uart_irq(), назначенный через serial_irq_set(). .
А отладчиком пройти ?
Сейчас основная задача слепить на этой UART RS-485 Modbus
Бросьте бяку! Этому говноизобретению конца 70-х давно место на помойке.
Хороший web-сервер куда нужнее.
 

pvvx

Активный участник сообщества
Бросьте бяку! Этому говноизобретению конца 70-х давно место на помойке.
Хороший web-сервер куда нужнее.
Бяка и нужна для демо web-сервера :) Как-же без неё? Не Siemens же протоколы вставлять для работы с внешними ПЛК и т.д. Дети и рос.производители не поймут :) Программу 'импорто-замещения' надо выполнять :p
Web серверов на RTOS толпа. Выбирайте и дописывайте на свой лад. К примеру ставьте хоть весь CycloneTCP_SSL_Crypto Open или подобное.
Если раздолбать UART до modbus, то простой TCP2UART тоже будет. А в SDK его нет. Тот который есть - глюк. В "Realtek Ameba uart adapter" писатели SDK не доделали даже ветку FlowControl... начали и бросили...
 
Последнее редактирование:

pvvx

Активный участник сообщества
А отладчиком пройти ?
Чтение регистра RUART_INT_ID_REG_OFF в uart_irq() вызывает сброс второго прерывания Tx.
Код:
void uart_irq(uint32_t id, SerialIrq event)
{
    serial_t    *sobj = (void*)id;

    int i, len;

    if(event == RxIrq) {
        gpio_write(&gpio_out2, 0);
        gpio_write(&gpio_out2, 1);
        len=_strlen(rx_buf);
        if(len > sizeof(rx_buf)-0x100) len = 0;
        rx_done++;
        DiagSPrintf(&rx_buf[len],"IntRx[%d]: INTID=0x%02x, INTEN=0x%02x\r\n", rx_done,
                HAL_RUART_READ32(sobj->hal_uart_adp.UartIndex, RUART_INT_ID_REG_OFF),
                HAL_RUART_READ32(sobj->hal_uart_adp.UartIndex, RUART_INTERRUPT_EN_REG_OFF));

        while(serial_readable(sobj))
            serial_putc(sobj, serial_getc(sobj));
    }

    if(event == TxIrq) {
        gpio_write(&gpio_out1, 0);
        gpio_write(&gpio_out1, 1);
        len=_strlen(rx_buf);
        if(len > sizeof(rx_buf)-0x100) len = 0;
        tx_done++;
        DiagSPrintf(&rx_buf[len],"IntTx[%d]: INTID=0x%02x, INTEN=0x%02x\r\n", tx_done,
                HAL_RUART_READ32(sobj->hal_uart_adp.UartIndex, RUART_INT_ID_REG_OFF),
                HAL_RUART_READ32(sobj->hal_uart_adp.UartIndex, RUART_INTERRUPT_EN_REG_OFF));
}
Итог:
IntRx[1]: INTID=0xcc, INTEN=0x05
IntTx[1]: INTID=0xc2, INTEN=0x05


Если убрать чтение HAL_RUART_READ32(sobj->hal_uart_adp.UartIndex, RUART_INT_ID_REG_OFF), тогда:
IntRx[1]: INTEN=0x05
IntTx[1]: INTEN=0x05
IntTx[2]: INTEN=0x05


Обращение отладчиком или чтение регистров UART во время работы приводит к зависанию...
 

MikeK

Member
Если раздолбать UART до modbus, то простой TCP2UART тоже будет. А в SDK его нет. Тот который есть - глюк. В "Realtek Ameba uart adapter" писатели SDK не доделали даже ветку FlowControl... начали и бросили...
Добрый вечер,
скажите, можно ли использовать RTL00 в качестве serial wifi? неважно, через AT команды или "прозрачный мост", которого пока нет (как я понял).
Вчера читал разные темы где вы рекомендовали не использовать ESP и сказали что RTL это лучше. У меня есть платки RTL00, но пока я даже терминалкой к ней не подключался ибо расчитывал на ESP с вашей прошивкой TCP2UART.
В общем главный для меня вопрос - лучше использовать RTL для такой задачи и возможно ли без своего писательства прошивки (т.е. надежна ли работа модуля если задать режим через AT команды?
Спасибо.
 

pvvx

Активный участник сообщества
Добрый вечер,
скажите, можно ли использовать RTL00 в качестве serial wifi?
Есть там в AT "прозрачный мост". Даже работает. Но управлять по AT не всегда удобно. Больших сложностей в собственном описании UART-TCP с RTOS нет и не было на устройствах с такими характеристиками. Слишком простая задача. Описание которое тут уже накатал вам занимает раза в три раза больше букв, чем писать на СИ. :)
Открыть сокет, и в цикле передавать принимаемые данные из сокета в UART, а принимаемые из UART отправлять в сокет. Можно для UART даже буера сделать, если зада того требует - это ещё строчка или две на СИ :)
 
Последнее редактирование:

MikeK

Member
Есть там в AT "прозрачный мост". Даже работает. Но управлять по AT не всегда удобно.
Больших сложностей в собственном описании UART-TCP с RTOS нет и не было на устройствах с такими характеристиками. Слишком простая задача. Описание которое тут уже накатал вам занимает раза в три раза больше букв, чем писать на СИ. :)
Открыть сокет, и в цикле передавать принимаемые данные из сокета в UART, а принимаемые из UART отправлять в сокет. Можно для UART даже буера сделать, если зада того требует - это ещё строчка или две на СИ :)
ну как бы понятно что когда рука набита то эта задача простая... но у меня пока не средств разработки, ничего...
ну и опыта.
попробую пока через AT когда подключусь...
скажите, а эта проблема с задержкой передачи тоже всплывет?
 

pvvx

Активный участник сообщества
ну как бы понятно что когда рука набита то эта задача простая... но у меня пока не средств разработки, ничего...
ну и опыта.
попробую пока через AT когда подключусь...
скажите, а эта проблема с задержкой передачи тоже всплывет?
C AT, который в SDK в исходниках, задержки не анализировал, а на вид - ввод-вывод текста их нет.
Если вы посмотрите разные модули с RTL, то большинство из них продается именно как TCP-UART переходник. Например RAK47x модули. Прошивка от них работает - проверили уже - смотрите тему про модули RTL.
 

Юрий Ботов

Moderator
Команда форума
Вопросик к опытным людям: Правильно ли я из всего этого понял что базовые адреса uart-ов RTL-ки в документации описаны правильно, а регистры uart RTL-ки (и их смещение и наполнение) в целом соответствуют стандартному 16550? Так уж случилось что хочу к uart достучаться мимо c-api... Есть аналогичное желание к записи во флэш, но это уже другая история.
 

pvvx

Активный участник сообщества
Вопросик к опытным людям: Правильно ли я из всего этого понял что базовые адреса uart-ов RTL-ки в документации описаны правильно, а регистры uart RTL-ки (и их смещение и наполнение) в целом соответствуют стандартному 16550? Так уж случилось что хочу к uart достучаться мимо c-api... Есть аналогичное желание к записи во флэш, но это уже другая история.
Uart-ы в "целом соответствуют стандартному 16550".
Реализация книжек по Spic и аналоги не найдены.
Короткая инициализация Spic для MXIC Flash SIO/DIO описана в RTL00MP3/rtl_boot.c at master · pvvx/RTL00MP3 · GitHub . Далее Flash отображается в 128 мегабайтной области и чтение-запись в неё осуществляется через неё. Стирание - отдельно, через регистры, процедурами в ROM. Через регистры Spic запись и чтение Flash быстрее при больших блоках... Смотрите другие темы...
 
Последнее редактирование:

Neov

Member
@pvvx драйвер для Modbus удался? прерывание по окончанию передачи символа смогли получить??
 

pvvx

Активный участник сообщества
@pvvx драйвер для Modbus удался? прерывание по окончанию передачи символа смогли получить??
Давно, там прерывание с флагами
IIR[0:3]:
0000 = modem status
0001 = no interrupt pending
0010 = THR empty
0100 = received data available
0110 = receiver line status
0111 = busy detect
1100 = character timeout - как и положено в Modbus, спустя задержку, тишину после последнего символа...
 

pvvx

Активный участник сообщества
Функция (реверс) прерывания UART в ROM-BIOS.
Совершенно не понятно, зачем там счетчик в 5 раз:
Код:
void _UartIrqHandle(void *data){
    PHAL_RUART_ADAPTER pru = (PHAL_RUART_ADAPTER) data;
    u32 puart = UART0_REG_BASE + (pru->UartIndex*RUART_REG_OFF);
    int i = 5;
    do {
        u8 val = HAL_READ8(puart, RUART_INT_ID_REG_OFF);
        if(val & RUART_IIR_INT_PEND) break;
        switch((val>>1) & 7) {
            case 6: // character timeout
            case 2: // received data available
                if((pru->State & 1) == HAL_UART_STATE_BUSY_RX) {
                    while(pru->RxCount) {
                        if(!(HAL_READ32(puart, RUART_LINE_STATUS_REG_OFF) & RUART_LINE_STATUS_REG_DR))
                            goto switch_end;
                        *pru->pRxBuf = HAL_READ32(puart, RUART_REV_BUF_REG_OFF);
                        pru->RxCount--;
                        pru->pRxBuf++;
                    }
                    if(!(pru->RxDRCallback)) {
                        pru->Interrupts &= ~(RU_IER_ERBFI|RU_IER_ELSI);
                        HalRuartSetIMRRtl8195a(pru);
                    }
                    pru->Status |= (HAL_READ32(puart, RUART_LINE_STATUS_REG_OFF) & 0x9E);
                    if(pru->State == HAL_UART_STATE_BUSY_RX)
                        pru->State = HAL_UART_STATE_READY;
                    else
                        pru->State = HAL_UART_STATE_BUSY_TX;
                    if(pru->RxCompCallback)
                        pru->RxCompCallback(pru->RxCompCbPara);
                } else {
                    while(HAL_READ32(puart, RUART_LINE_STATUS_REG_OFF) & RUART_LINE_STATUS_REG_DR) {
                        if(pru->RxDRCallback)
                            pru->RxDRCallback(pru->RxDRCbPara);
                    }
                }
                break;
           case 1: // THR empty
              if((pru->State & (~2)) == HAL_UART_STATE_BUSY_TX) {
                  while(pru->TxCount) {
                      if(!(HAL_READ32(puart, RUART_LINE_STATUS_REG_OFF) & RUART_LINE_STATUS_REG_THRE))
                          goto switch_end;
                        HAL_WRITE32(puart, RUART_TRAN_HOLD_REG_OFF, (u8)*pru->pTxBuf);
                        pru->pTxBuf++;
                        pru->TxCount--;
                  }
                    // Disable Transmit Holding Register Empty Interrupt
                    pru->Interrupts &= ~RU_IER_ETBEI;
                    HalRuartSetIMRRtl8195a(pru);
                    if(pru->State == HAL_UART_STATE_BUSY_TX)
                        pru->State = HAL_UART_STATE_READY;
                    else
                        pru->State = HAL_UART_STATE_BUSY_RX;
                    if(pru->TxCompCallback)
                        pru->TxCompCallback(pru->TxCompCallback);
              } else {
                  if(pru->TxTDCallback)
                      pru->TxTDCallback(pru->TxTDCbPara);
              }
              break;
           case 3: // receiver line status / busy detect?
              pru->Status |= (HAL_READ32(puart, RUART_LINE_STATUS_REG_OFF) & 0x9E);
               break;
           case 0:  // modem status?
              pru->ModemStatus = HAL_READ32(puart, RUART_MODEM_STATUS_REG_OFF);
              if(pru->ModemStatusInd)
                  pru->ModemStatusInd(pru);
               break;
        }
switch_end:
        i--;
    } while(i);
}
и без него работает. Код не 100% от ROM, а более компактный (собирается в 2/3 по объему от исходного в ROM - там накручено ужасно, с повторами опросов и дублями, но повторяет алгоритм на 100% по всем обращениям)
Чтобы сделать modbus, его надо переписывать, выведя и дополняя PTIME, Programmable THRE Interrupt Mode Enable обслуживание в HAL и прерывании...
 

pvvx

Активный участник сообщества
Потому что может быть сохранено до 5 типов прерываний и нужно опросить их все.
Т.е. у регистра RUART_LINE_STATUS_REG фифо глубиной в 5, как и у всех других регистров UART ? :) Иначе смысла то нет.
Без этого цикла успевает работать на 10 000 000 Baud, а с ним - нет.
Вообще, с данным кодом прерывания, из ROM и имеющимся HAL, наступают проблемы уже при 3 Мегабит (CPU 83МГц). Теряется даже это событие - прерывание по тишине в N символов. Наверняка этот цикл вписали как затычку - наобум, типа и так покатит :) Глупостей в коде ROM-BIOS куча.
Динамику сложно отлаживать с Jtag, проще вписывать метки с выводом инфы хоть в консоль, перекомпилить и заливать в RAM - это быстрее раз в десять, чем тыркаться с Jtag по шагам и точкам останова... Перекомпиляция и заливка по скорости уже приблизилась к интерактивному режиму - менее пары секунд весь процесс на сложный проект...
Это очень сильно отличает данные RTL-ы от ESP и прочих, в которых код исполняется из Flash. Т.е. отладка ускоряется неимоверно и рабочее итого без багов можно получить быстрее. А у Амебщиков - DAP-Link, а он тормоз и в коде видны их потуги отладки, которые нафиг не нужны в готовом проекте и занимающие только место в RAM :)...

Вот кому нужна их фигня в данном прерывании:
Код:
if ( ConfigDebugErr & 0x4000 )
        DiagPrintf("\r[UART Err]\x1B[31mUnknown Interrupt Type\n\x1B[0m");
Она только увеличивает глубину стека на сохранение регистров для вызова DiagPrintf() и тормозит обработку прерывания на загрузку лишних регистров и сравнение флагов...
В итоге им пришлось ограничить в спецификации скорость UART.
А сам HAL для UART написан неизвестно для кого. Типа примеры для 3-х случаев, совершенно разрозненные и не стыкующиеся. 3 - работа по пулл, прерываниям и DMA. Заголовки-структуры ужасно большие, но ничего хорошего не несут - не выполняется их смысл: конфигурации на все случаи жизни (для того и заводят переменные и флаги управления в структурах управления драйвером). Т.е. код написан как отписка наемного работника - типа ТЗ по галочкам выполнено - налепили, работает, а оптимизировать и состыковывать со всем остальным - нафиг :)

Драйвер для RS-485 под Modbus пока и не опубликован, т.к. требует переписывания всего HAL с UART.
Пока есть только не стыкующийся с текущим HAL вариант, а как его оптимизировать - жестко (фиксированные адреса периферии) или для разных UART с вычислением на ходу (UART0, UART1, UART2 и их пинмапы) в коде пока не решил... Универсальный, для динамического выбора в ходе работы используемой UART выходит тормознее и занимает раза в 4-ре больше кода, чем условная трансляция под конкретный номер UART c #if UART_IDX ... В итоге ограничивается скорость UART на уровне к 3Мбит/сек, а при условной трансляции и жесткого задания алго - там за 10Мбит/сек c оптимизацией передачи на DMA или если сообщение лезет в TX FIFO и прочие условия, то без запуска DMA (так итого быстрее).
 
Последнее редактирование:
Сверху Снизу