Исправить скорость SCI и добавить диагностику ошибок приёма RS232
Округлить делитель SCI по формуле аппаратуры, настроить вход RX и обработку ошибок FIFO. Добавить диагностические поля и проверки модели, установить 9600 бод для RS485 при Owen. Сохранить скрипт сборки, обновлённый образ прошивки и карту линковки.
This commit is contained in:
@@ -116,6 +116,10 @@ typedef struct
|
||||
volatile unsigned int fifo_tx_active, fifo_rx_guard;
|
||||
/* Объявляет fifo_rx_errors — данные fifo_rx_errors; fifo_overflows — данные fifo_overflows. volatile требует фактического чтения или записи при каждом доступе. */
|
||||
volatile unsigned long fifo_rx_errors, fifo_overflows;
|
||||
volatile unsigned long fifo_rx_bytes; /* Считает байты, реально прочитанные обработчиком из FIFO SCI-A; чтение этого поля в CCS не изменяет приёмник. */
|
||||
volatile unsigned int fifo_rx_last_word; /* Хранит последнее чтение SCIRXBUF: байт в битах 7:0, FE в бите 15 и PE в бите 14. */
|
||||
volatile unsigned int fifo_rx_last_status; /* Хранит SCIRXST последней ошибки до сброса: BREAK/FE/OE/PE в битах 5/4/3/2. */
|
||||
volatile unsigned int fifo_rx_last_error_word; /* Хранит слово FE/PE, вызвавшее сброс, либо ноль при общей ошибке SCI до чтения FIFO. */
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ static int RS_FifoStart(RS_DATA *, unsigned int *, unsigned long, int);
|
||||
/* Заполняет TX FIFO доступными байтами, сохраняя длину и положение в передаваемом пакете. */
|
||||
static void RS_FifoTx(RS_DATA *);
|
||||
/* Прерывает ошибочный приём FIFO, очищает аппаратное состояние и включает защитную паузу. */
|
||||
static void RS_FifoAbort(RS_DATA *);
|
||||
static void RS_FifoAbort(RS_DATA *, unsigned int); /* Принимает слово с признаками FE/PE либо ноль при общей ошибке SCI; сохраняет причину до очистки регистров. */
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
|
||||
@@ -195,7 +195,7 @@ void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
/* Проверяет if (rs_arr->SciRegs->SCIFFRX.bit.RXFFOVF или rs_arr->SciRegs->SCIRXST.bit.RXERROR); последующий оператор выполняется только при истинном условии. */
|
||||
if (rs_arr->SciRegs->SCIFFRX.bit.RXFFOVF || rs_arr->SciRegs->SCIRXST.bit.RXERROR) {
|
||||
/* Вызывает RS_FifoAbort. Прерывает ошибочный приём FIFO, очищает аппаратное состояние и включает защитную паузу. */
|
||||
RS_FifoAbort(rs_arr); return;
|
||||
RS_FifoAbort(rs_arr,0); return; /* Сохраняет SCIRXST при общей ошибке или переполнении; SCIRXBUF здесь не читался. */
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Проверяет if (!rs_arr->SciRegs->SCIFFRX.bit.RXFFST); последующий оператор выполняется только при истинном условии. */
|
||||
@@ -209,8 +209,10 @@ void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
received=rs_arr->SciRegs->SCIRXBUF.all; /* one pop, data + FE/PE */ /* Записывает received значением rs_arr->SciRegs->SCIRXBUF.all; данные received. */
|
||||
/* Проверяет if (received & 0xC000U); последующий оператор выполняется только при истинном условии. */
|
||||
if (received & 0xC000U) { RS_FifoAbort(rs_arr); return; }
|
||||
rs_arr->fifo_rx_bytes++; /* Считает реальные чтения байтов из FIFO, включая повреждённые и пропущенные во время защитной паузы. */
|
||||
rs_arr->fifo_rx_last_word=received; /* Сохраняет данные в битах 7:0 и признаки FE/PE в битах 15:14, позволяя смотреть их в RAM без чтения FIFO отладчиком. */
|
||||
/* Маска 0xC000 из описания SCIRXBUF в TI SPRUI07 выбирает ошибку стопового бита FE и ошибку чётности PE текущего байта. */
|
||||
if (received & 0xC000U) { RS_FifoAbort(rs_arr,received); return; } /* Передаёт повреждённое слово диагностике до сброса FIFO и отвергает весь пакет. */
|
||||
/* Проверяет if (rs_arr->fifo_rx_guard); последующий оператор выполняется только при истинном условии. */
|
||||
if (rs_arr->fifo_rx_guard) { rs_arr->fifo_rx_guard=4; continue; }
|
||||
/* Записывает Rc значением received & 255U; данные Rc. */
|
||||
@@ -719,13 +721,15 @@ int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len)
|
||||
void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Объявляет SciBaud — SCI скорость передачи. */
|
||||
long SciBaud;
|
||||
|
||||
/* Записывает SciBaud значением LSPCLK/(speed*8.0); SCI скорость передачи. */
|
||||
SciBaud = LSPCLK/(speed*8.0);
|
||||
|
||||
// if((SciBaud-(unsigned int)SciBaud)>0.5) SciBaud++;
|
||||
unsigned long SciBaud; /* Хранит 16-битный BRR в 32-битном типе, чтобы до вычитания единицы представить делитель 65536. */
|
||||
unsigned long baud_clock; /* Хранит частоту выборки SCI в Гц: по TI SPRUI07 на один бит приходится восемь тактов. */
|
||||
if (!speed || speed > 0xFFFFFFFFUL/8UL || LSPCLK <= 0) return; /* Исключает деление на ноль, переполнение 32-битного произведения и настройку до определения частоты SCI. */
|
||||
baud_clock=speed*8UL; /* Переводит скорость в бодах в требуемую частоту восьмикратной выборки без вычислений с плавающей точкой. */
|
||||
SciBaud=(unsigned long)LSPCLK/baud_clock; /* Вычисляет целую часть отношения LSPCLK к частоте выборки; это BRR+1 согласно формуле TI. */
|
||||
if ((unsigned long)LSPCLK%baud_clock >= (baud_clock+1UL)/2UL) SciBaud++; /* Округляет делитель к ближайшему целому по остатку, не складывая большие частоты с риском переполнения. */
|
||||
if (SciBaud < 2UL) SciBaud=2UL; /* Ограничивает максимальную скорость значением LSPCLK/16; BRR=0 тоже имеет этот особый предел по TI SPRUI07. */
|
||||
if (SciBaud > 65536UL) SciBaud=65536UL; /* Ограничивает отношение диапазоном 16-битного BRR+1, чтобы малая скорость не оборачивала регистр. */
|
||||
SciBaud--; /* Преобразует отношение в BRR: при 60 МГц и 115200 бод получает 64, что даёт 115384,6 бод вместо прежних 113636,4. */
|
||||
|
||||
/* Записывает rs_arr->SciRegs->SCIHBAUD значением HIBYTE((int)SciBaud); rs arr SCI Regs SCIHBAUD. */
|
||||
rs_arr->SciRegs->SCIHBAUD = HIBYTE((int)SciBaud);
|
||||
@@ -781,6 +785,8 @@ void setup_uart(char commnumber, unsigned long speed_baud)
|
||||
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // SCITXDA - SCI-A transmit(O)
|
||||
/* Записывает GpioCtrlRegs.GPAMUX2.bit.GPIO28 значением 1; аппаратная линия ввода/вывода GPIO28. */
|
||||
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // SCIRXDA - SCI-A receive (I)
|
||||
GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; /* Выбирает асинхронный вход SCIRXDA по TI SPRUI07; исключает задержки фильтра GPIO, оставшиеся после другой программы или JTAG. */
|
||||
GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; /* Включает внутреннюю подтяжку входа RX к уровню покоя UART, чтобы неподключённый вход не создавал ложные старты. */
|
||||
|
||||
/* Записывает PieVectTable.SCIRXINTA значением &RSA_RX_Handler; данные SCIRXINTA. */
|
||||
PieVectTable.SCIRXINTA = &RSA_RX_Handler;
|
||||
@@ -867,6 +873,7 @@ void setup_uart(char commnumber, unsigned long speed_baud)
|
||||
#if RS232_USE_FIFO
|
||||
/* Проверяет if (commnumber == COM_1); последующий оператор выполняется только при истинном условии. */
|
||||
if (commnumber == COM_1) {
|
||||
SciRegs->SCICTL1.bit.RXERRINTENA=1; /* Разрешает отдельное RX-прерывание по BREAK/RXERROR: в FIFO-режиме BREAK может не положить байт в FIFO и не достичь порога RXFFIL. */
|
||||
SciRegs->SCIFFTX.all=0xC008U; /* enhancement, reset held, TX level 8, IRQ off */ /* Записывает SciRegs->SCIFFTX.all значением 0xC008U; представление регистра целым словом без разбиения на битовые поля. */
|
||||
SciRegs->SCIFFRX.all=0x0061U; /* reset held, RX level 1, IRQ on */ /* Записывает SciRegs->SCIFFRX.all значением 0x0061U; представление регистра целым словом без разбиения на битовые поля. */
|
||||
/* Записывает SciRegs->SCIFFCT.all значением 0; представление регистра целым словом без разбиения на битовые поля. */
|
||||
@@ -883,6 +890,10 @@ void setup_uart(char commnumber, unsigned long speed_baud)
|
||||
rs_arr->fifo_tx_active=rs_arr->fifo_rx_guard=0;
|
||||
/* Записывает rs_arr->fifo_rx_errors значением rs_arr->fifo_overflows=0; данные rs_arr->fifo_rx_errors. */
|
||||
rs_arr->fifo_rx_errors=rs_arr->fifo_overflows=0;
|
||||
rs_arr->fifo_rx_bytes=0; /* Начинает счёт реальных чтений FIFO заново при настройке SCI-A. */
|
||||
rs_arr->fifo_rx_last_word=0; /* До первого чтения FIFO диагностическое слово не содержит старых данных RAM. */
|
||||
rs_arr->fifo_rx_last_status=0; /* Очищает сохранённые признаки BREAK, FE, OE и PE предыдущего запуска. */
|
||||
rs_arr->fifo_rx_last_error_word=0; /* Очищает сохранённый повреждённый байт и его признаки FE/PE. */
|
||||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||||
} else
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
@@ -1071,6 +1082,7 @@ static void RS_FifoTx(RS_DATA *rs_arr)
|
||||
enableUARTInt(rs_arr);
|
||||
/* Записывает rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA значением 1; данные RXFFIENA. */
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA=1;
|
||||
rs_arr->SciRegs->SCICTL1.bit.RXERRINTENA=1; /* Возвращает обработку BREAK и ошибок приёмника вместе с RX FIFO после завершения передачи. */
|
||||
/* Записывает rs_arr->fifo_tx_active значением 0; данные rs_arr->fifo_tx_active. */
|
||||
rs_arr->fifo_tx_active=0;
|
||||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||||
@@ -1125,6 +1137,7 @@ static int RS_FifoStart(RS_DATA *rs_arr,unsigned int *buffer,unsigned long count
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=0;
|
||||
/* Записывает rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA значением 0; данные RXFFIENA. */
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA=0;
|
||||
rs_arr->SciRegs->SCICTL1.bit.RXERRINTENA=0; /* Запрещает сброс SCI по шуму RX во время TX, когда прерывания приёма FIFO также отключены. */
|
||||
/* Вызывает enableUARTIntW с аргументами (rs_arr) в текущей последовательности операций. */
|
||||
enableUARTIntW(rs_arr);
|
||||
/* Вызывает RS_SetBitMode с аргументами (rs_arr,8) в текущей последовательности операций. */
|
||||
@@ -1152,9 +1165,11 @@ static int RS_FifoStart(RS_DATA *rs_arr,unsigned int *buffer,unsigned long count
|
||||
}
|
||||
|
||||
/* Прерывает ошибочный приём FIFO, очищает аппаратное состояние и включает защитную паузу. */
|
||||
static void RS_FifoAbort(RS_DATA *rs_arr)
|
||||
static void RS_FifoAbort(RS_DATA *rs_arr,unsigned int error_word) /* Получает считанное слово FE/PE либо ноль, если ошибка обнаружена до чтения FIFO. */
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
rs_arr->fifo_rx_last_status=rs_arr->SciRegs->SCIRXST.all; /* Сохраняет SCIRXST до SWRESET: биты 5/4/3/2 означают BREAK/FE/OE/PE по TI SPRUI07. */
|
||||
rs_arr->fifo_rx_last_error_word=error_word; /* Сохраняет признаки FE/PE и значение повреждённого байта; ноль означает проверку общей ошибки до чтения SCIRXBUF. */
|
||||
/* Изменяет счётчик в выражении rs_arr->fifo_rx_errors++; на один для следующего шага. */
|
||||
rs_arr->fifo_rx_errors++;
|
||||
/* Проверяет if (rs_arr->SciRegs->SCIFFRX.bit.RXFFOVF) rs_arr->fifo_overflows++; последующий оператор выполняется только при истинном условии. */
|
||||
|
||||
@@ -109,7 +109,7 @@ void main()
|
||||
setup_uart(COM_1,115200);
|
||||
|
||||
/* Проверяет if(Owen)setup_uart(COM_2,57600); последующий оператор выполняется только при истинном условии. */
|
||||
if(Owen)setup_uart(COM_2,115200);
|
||||
if(Owen)setup_uart(COM_2,9600);
|
||||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||||
else setup_uart(COM_2,115200);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user