Files
Balsam_167/Source/Internal/RS485.c

628 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file RS485.c
* @brief Драйвер двух каналов SCI/RS-485 и автоматы приёма/передачи кадров.
*
* Настраивает SCI-A/SCI-B, обслуживает RX/TX-прерывания, контролирует длины
* команд и тайм-аут активности, а также переключает формат и скорость линии.
* RS_DATA содержит разделяемое состояние конечного автомата; буферы должны
* жить до завершения передачи и не превышать MAX_*_LENGTH. Обработчики обязаны
* подтверждать PIE и корректно возвращать приоритеты прерываний.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
RS485.с
****************************************************************
* Процедуры работы с UART *
****************************************************************/
//#include "big_dsp_module.h"
#include "DSP2833x_Device.h"
#include "DSP2833x_SWPrioritizedIsrLevels.h"
#include "RS485.h"
#include "bios_dsp.h"
#include "cntrl_adr.h"
#include "tools.h"
//#include "flash_tools.h"
RS_DATA rs_a,rs_b;
unsigned int RS_Len[70]={0};
static char size_cmd15=1;
void RS_RX_Handler(RS_DATA *rs_arr);
void RS_TX_Handler(RS_DATA *rs_arr);
/** Обработчик прерываний UART - принато */
/**
* @brief ISR приёма SCI-A.
* @details Временно ограничивает приоритеты группы PIE9, вызывает общий
* RS_RX_Handler() для rs_a, затем восстанавливает маску и подтверждает группу.
*/
interrupt void RSA_RX_Handler(void)
{
// Set interrupt priority:
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
IER |= M_INT9;
IER &= MINT9; // Set "global" priority
PieCtrlRegs.PIEIER9.all &= MG91; // Set "group" priority
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
EINT;
clear_timer_rs_live(&rs_a);
RS_RX_Handler(&rs_a);
// Restore registers saved:
DINT;
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** @brief ISR приёма SCI-B; адаптер общего автомата к состоянию rs_b. */
interrupt void RSB_RX_Handler(void)
{
// Set interrupt priority:
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
IER |= M_INT9;
IER &= MINT9; // Set "global" priority
PieCtrlRegs.PIEIER9.all &= MG93; // Set "group" priority
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
EINT;
clear_timer_rs_live(&rs_b);
RS_RX_Handler(&rs_b);
// Restore registers saved:
DINT;
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** @brief ISR освобождения TX SCI-A; продолжает передачу буфера rs_a. */
interrupt void RSA_TX_Handler(void)
{
// Set interrupt priority:
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
IER |= M_INT9;
IER &= MINT9; // Set "global" priority
PieCtrlRegs.PIEIER9.all &= MG92; // Set "group" priority
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
EINT;
clear_timer_rs_live(&rs_a);
RS_TX_Handler(&rs_a);
// Restore registers saved:
DINT;
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** @brief ISR освобождения TX SCI-B; продолжает передачу буфера rs_b. */
interrupt void RSB_TX_Handler(void)
{
// Set interrupt priority:
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
IER |= M_INT9;
IER &= MINT9; // Set "global" priority
PieCtrlRegs.PIEIER9.all &= MG94; // Set "group" priority
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
EINT;
clear_timer_rs_live(&rs_b);
RS_TX_Handler(&rs_b);
// Restore registers saved:
DINT;
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** Обработчик прерываний UART - принато */
/**
* @brief Принимает очередной символ и продвигает автомат сборки кадра.
* @param rs_arr Состояние порта, вызвавшего прерывание.
* @details Проверяет аппаратные ошибки, адресный девятый бит, ожидаемую длину
* команды и границы буфера. После полного кадра выставляет признак готовности
* для foreground-кода; при нарушении синхронизации возвращается к ожиданию адреса.
* @warning Выполняется из ISR и не должен вызывать блокирующие операции.
*/
void RS_RX_Handler(RS_DATA *rs_arr)
{
char Rc;
char RS_BytePtr;
// led1_on();
for(;;) // 'goto' это не оператор азыка С
{
if(!rs_arr->SciRegs->SCIRXST.bit.RXRDY) // Receiver ready flag
{
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1; // Clear INT flag
return; // кстати это единственный выход из прерываниа
}
Rc = rs_arr->SciRegs->SCIRXBUF.bit.RXDT; // Читаем символ в любом случае
if(rs_arr->SciRegs->SCIRXST.bit.RXERROR) // Receiver error flag
{
rs_arr->SciRegs->SCICTL1.bit.SWRESET=0; // Reset SCI
rs_arr->SciRegs->SCICTL1.bit.SWRESET=1; // Relinquish SCI from Reset
continue;
}
if(rs_arr->RS_DataReady) continue; // Не забрали данные
if (rs_arr->RS_Flag9bit==1) // дла RS485????????
{
// Инициализируем переменные и флаги
rs_arr->RS_FlagBegin = true; // Ждем заголовок
rs_arr->RS_RecvLen = 0;
rs_arr->RS_FlagSkiping = false;
rs_arr->RS_HeaderCnt = 0;
rs_arr->RS_Cmd = 0;
}
if(rs_arr->RS_FlagSkiping) continue; // Не нам
if (rs_arr->RS_FlagBegin) // Заголовок
{
if (rs_arr->RS_HeaderCnt==0) // Адрес контроллера или стандартнаа команда
{
if( (Rc == CNTRL_ADDR_UNIVERSAL) || (Rc == CNTRL_ADDR && CNTRL_ADDR!=0) || ((Rc == rs_arr->addr_answer) && rs_arr->flag_LEADING)
|| ((Rc == ADDR_FOR_ALL && ADDR_FOR_ALL!=0) && !rs_arr->flag_LEADING))
{
rs_arr->addr_recive=Rc; // запомнили адрес по которому нас запросили
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Первый байт
RS_SetBitMode(rs_arr,8); // перестроились в 8-бит режим
}
else
{
rs_arr->RS_FlagSkiping = true; // Не нашему контроллеру
rs_arr->RS_FlagBegin = false; // остались в 9-бит режиме
// led1_off();
}
}
else
{
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Второй байт и т.д.
if (rs_arr->RS_HeaderCnt == 7 && rs_arr->RS_Cmd==CMD_MODBUS_16 && !rs_arr->flag_LEADING)
{
RS_Len[CMD_MODBUS_16] = (10+Rc);
}
if (rs_arr->RS_HeaderCnt == 3)
if (rs_arr->RS_Cmd == ANS_MODBUS_4)
{
RS_Len[rs_arr->RS_Cmd] = Rc + 5;
}
// если второй байт - это команда
if (rs_arr->RS_HeaderCnt == 2)
{
rs_arr->RS_Cmd = Rc;
// Проверка длины посылки
// CMD_LOAD - младшаа на данный момент
// CMD_STD_ANS - старшаа на данный момент
if ((rs_arr->RS_Cmd < CMD_MODBUS_3) || (rs_arr->RS_Cmd > CMD_STD_ANS) || (RS_Len[rs_arr->RS_Cmd]<3)
|| ((rs_arr->RS_Cmd == CMD_LOAD)&&(rs_arr->RS_PrevCmd != CMD_INITLOAD))
)
{
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
rs_arr->RS_HeaderCnt = 0; // Потому что команда не та
rs_arr->RS_FlagBegin = true;
rs_arr->RS_FlagSkiping = false;
rs_arr->RS_Cmd=0;
// led1_off();
continue;
}
if (rs_arr->RS_Cmd == CMD_LOAD) // Дла этой команды заголовок очень короткий
rs_arr->RS_FlagBegin = false;// дальше идут данные
}
if( (rs_arr->RS_HeaderCnt >= RS_Len[rs_arr->RS_Cmd]) ||
(rs_arr->RS_HeaderCnt >= sizeof(rs_arr->RS_Header)))
{ // Получили заголовок
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
rs_arr->RS_FlagBegin = false;
rs_arr->RS_FlagSkiping = true;
rs_arr->RS_DataReady = true;
rs_arr->RS_Cmd=0;
// led1_off();
} } }
else // Поток данных
{
if(rs_arr->pRS_RecvPtr<(unsigned int *)Rec_Bloc_Begin || rs_arr->pRS_RecvPtr>(unsigned int *)Rec_Bloc_End)
{
rs_arr->pRS_RecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
rs_arr->pRecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
}
if(rs_arr->RS_PrevCmd != CMD_INITLOAD) continue; // Мы здесь оказались по какой-то чудовищной ошибке
if(rs_arr->RS_DataReady) // Если данные в основном цикле не забраны,
{ // то пропускаем следующую посылку
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
// led1_off();
continue;
}
RS_BytePtr = rs_arr->RS_RecvLen++ % 2;
if(RS_BytePtr) *rs_arr->pRS_RecvPtr++ |= Rc; // Получили слово
else *rs_arr->pRS_RecvPtr = Rc<<8;
if(rs_arr->RS_Length <= rs_arr->RS_RecvLen) // Конец посылки
{
rs_arr->RS_PrevCmd = rs_arr->RS_Header[1] = CMD_LOAD;
RS_SetBitMode(rs_arr,9); // Получили все данные перестроились в 9-бит дла RS485?
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
rs_arr->RS_DataReady = true; // Флаг в основной цикл - данные получены
// led1_off();
} } } }
/** Обработчик прерываний UART - послано */
/**
* @brief Передаёт следующий элемент активного RS-485 буфера.
* @param rs_arr Состояние обслуживаемого SCI.
* @details Пока счётчик не достиг RS_Length, пишет следующий байт в SCITXBUF.
* После последнего байта дожидается освобождения линии, возвращает трансивер
* в режим приёма и сбрасывает состояние передачи.
*/
void RS_TX_Handler(RS_DATA *rs_arr)
{
char RS_BytePtr;
// unsigned int i;
if(rs_arr->RS_SendBlockMode == BM_CHAR32)
{
if(++rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
}
SCI_send(rs_arr,*(rs_arr->pRS_SendPtr++));
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
RS_Wait4OK(rs_arr);
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
rs_arr->flag_TIMEOUT_to_Send=false; /* сбросили флаг ожиданиа таймаута */
}
}
else /* BM_PACKED */
{
RS_BytePtr = (rs_arr->RS_SendLen++) % 2;
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
}
if(RS_BytePtr) SCI_send(rs_arr, LOBYTE( *(rs_arr->pRS_SendPtr++) ));
else SCI_send(rs_arr, HIBYTE( *rs_arr->pRS_SendPtr ));
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
RS_Wait4OK(rs_arr);
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
// RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
// RS_Line_to_receive(); /* режим приема RS485 */
}
}
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
// rs_arr->SciRegs->SCIFFTX.bit.TXINTCLR=1; // Clear INT flag
}
/** Инициализациа массива длин команд */
/**
* @brief Заполняет таблицу ожидаемых длин сервисных и Modbus-команд.
* @post RS_Len[код] содержит полную длину кадра для поддерживаемых команд.
*/
void setup_arr_cmd_length()
{
int i;
for (i=0;i<70;i++) RS_Len[i]=i;
RS_Len[CMD_LOAD] = 12;
RS_Len[CMD_UPLOAD] = 12;
RS_Len[CMD_RUN] = 8;
RS_Len[CMD_XFLASH] = 9;
RS_Len[CMD_TFLASH] = 16;
RS_Len[CMD_PEEK] = 8;
RS_Len[CMD_POKE] = 12;
RS_Len[CMD_INITLOAD] = 12;
RS_Len[CMD_INIT] = 5;
RS_Len[CMD_VECTOR] = size_cmd15-2; //sizeof(CMD_TO_TMS)-2;
RS_Len[CMD_STD] = size_cmd15-1; //sizeof(CMD_TO_TMS)-1;
RS_Len[CMD_IMPULSE] = 8;
RS_Len[CMD_MODBUS_3] = 8;
RS_Len[ANS_MODBUS_4] = 3+48*2+2;
RS_Len[CMD_MODBUS_6] = 8;
RS_Len[CMD_MODBUS_16] = 13;
RS_Len[CMD_MODBUS_15] = 27;
RS_Len[CMD_EXTEND] = 18;
}
/** Настройка режима приема/передачи */
/**
* @brief Переключает SCI между 8- и 9-битным форматом символа.
* @param rs_arr Настраиваемый порт.
* @param n Требуемое число бит данных.
*/
void RS_SetBitMode(RS_DATA *rs_arr,int n)
{
if(n == 8)
{
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
rs_arr->RS_Flag9bit=0;
}
if(n == 9)
{
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
rs_arr->RS_Flag9bit=1;
} }
/** Посылка блока байтов.
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param buf адрес массива
@param len количество байт
@see RS_BSend, RS_TRANSMIT_INTR */
/**
* @brief Запускает передачу массива, где один элемент хранит один байт.
* @return 1 после успешного запуска, 0 если порт занят или длина недопустима.
* @note Первый адресный символ отправляется в 9-битном режиме, оставшиеся — в 8-битном.
*/
int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf,unsigned long len)
{
unsigned int i;
for (i=0; i <= 30000; i++){} /* Пауза дла PC */
RS_Line_to_send(rs_arr); /* режим передачи RS485 */
for (i=0; i <= 10000; i++){} /* Пауза дла PC */
rs_arr->RS_SLength = len; /* Настраиваем переменные */
rs_arr->pRS_SendPtr = pBuf + 1;
rs_arr->RS_SendBlockMode = BM_CHAR32;
RS_Wait4OK(rs_arr); /* Дожидаемса ухода */
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
rs_arr->RS_SendLen = 1; /* Два байта уже передали */
if(len > 1)
{
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
}
else
{
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
RS_Wait4OK(rs_arr); /* Дожидаемса ухода без прерываниа */
for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
RS_SetBitMode(rs_arr,9); /* Обратно в 9-бит режим */
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
}
return 0;
}
// Посылка блока упакованных байтов
/**
* @brief Запускает передачу массива с байтами, упакованными в слова DSP.
* @return 1 после успешного запуска, 0 при занятом порте или ошибке длины.
*/
int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len)
{
RS_Line_to_send(rs_arr); // режим передачи RS485
rs_arr->RS_SLength = len; // Настраиваем переменные
rs_arr->pRS_SendPtr = pBuf;
rs_arr->RS_SendBlockMode = BM_PACKED;
RS_Wait4OK(rs_arr); // Ожидаем очистки и ухода последнего байта
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
rs_arr->RS_SendLen = 1; // Один байт уже передали
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
SCI_send(rs_arr,HIBYTE(*pBuf));// Передаем первый байт
return 0;
}
/** Устанавливает скорость обмена.
@param speed скорость RS в бод */
/** Устанавливает скорость обмена.
@param speed скорость RS в бод */
/**
* @brief Пересчитывает делитель baud-rate выбранного SCI.
* @param speed Требуемая скорость в бодах.
* @pre speed больше нуля и достижима от LSPCLK.
*/
void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
{
long SciBaud;
SciBaud = LSPCLK/(speed*8.0);
// if((SciBaud-(unsigned int)SciBaud)>0.5) SciBaud++;
rs_arr->SciRegs->SCIHBAUD = HIBYTE((int)SciBaud);
rs_arr->SciRegs->SCILBAUD = LOBYTE((int)SciBaud);
}
/** Инициализациа последовательного порта */
/**
* @brief Обнуляет состояния обоих портов и создаёт таблицу длин команд.
* @param size_cmd15_set Прикладная длина команды функции 15.
*/
void create_uart_vars(char size_cmd15_set)
{
size_cmd15=size_cmd15_set;
rs_a.commnumber=COM_1;
rs_b.commnumber=COM_2;
}
/** Инициализациа последовательного порта */
/**
* @brief Назначает GPIO/векторы и запускает один из двух SCI-портов.
* @param commnumber COM_1 для SCI-A либо COM_2 для SCI-B.
* @param speed_baud Начальная скорость линии.
*/
void setup_uart(char commnumber, unsigned long speed_baud)
{
volatile struct SCI_REGS *SciRegs;
RS_DATA *rs_arr;
if(commnumber==COM_1)
{
rs_a.SciRegs = &SciaRegs;
rs_arr = &rs_a;
EALLOW;
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // SCITXDA - SCI-A transmit(O)
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // SCIRXDA - SCI-A receive (I)
PieVectTable.SCIRXINTA = &RSA_RX_Handler;
PieVectTable.SCITXINTA = &RSA_TX_Handler;
PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, INT1
PieCtrlRegs.PIEIER9.bit.INTx2=1; // PIE Group 9, INT2
IER |= M_INT9; // Enable CPU INT
EDIS;
}
if(commnumber==COM_2)
{
rs_b.SciRegs = &ScibRegs;
rs_arr = &rs_b;
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 2; // SCITXDB - SCI-B transmit(O)
GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 2; // SCIRXDB - SCI-B receive (I)
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // GPIO 34 - general purpose I/O 34 (default)
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // Configures the GPIO pin as an output
PieVectTable.SCIRXINTB = &RSB_RX_Handler;
PieVectTable.SCITXINTB = &RSB_TX_Handler;
PieCtrlRegs.PIEIER9.bit.INTx3=1; // PIE Group 9, INT3
PieCtrlRegs.PIEIER9.bit.INTx4=1; // PIE Group 9, INT4
IER |= M_INT9; // Enable CPU INT
EDIS;
}
rs_arr->commnumber = commnumber;
SciRegs = rs_arr->SciRegs;
RS_SetLineMode(rs_arr,8,'N',1);
// enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciRegs->SCIFFCT.bit.ABDCLR=1;
SciRegs->SCIFFCT.bit.CDC=0;
SciRegs->SCICTL1.bit.RXERRINTENA=0;
SciRegs->SCICTL1.bit.SWRESET=0;
SciRegs->SCICTL1.bit.TXWAKE=0;
SciRegs->SCICTL1.bit.SLEEP=0;
SciRegs->SCICTL1.bit.TXENA=1;
SciRegs->SCICTL1.bit.RXENA=1;
SciRegs->SCIFFTX.bit.SCIFFENA=0; // fifo off
SciRegs->SCIFFRX.bit.RXFFIL=1; // Длина наименьшей команды
setup_arr_cmd_length();
RS_SetLineSpeed(rs_arr,speed_baud); // скорость линии
RS_Line_to_receive(rs_arr); // режим приема RS485
enableUARTInt(rs_arr); // разрешение прерываний UART
RS_SetBitMode(rs_arr,9);
rs_arr->RS_PrevCmd = 0; // не было никаких команд
rs_arr->flag_TIMEOUT_to_Send = 0;
rs_arr->flag_LEADING = 0;
SciRegs->SCIFFRX.bit.RXFFINTCLR=1; // Clear INT flag
SciRegs->SCICTL1.bit.SWRESET=1; // Relinquish SCI from Reset
}
/** Настройка режима линии.
@param bit количество бит данных
@param parity режим четности (N,O,E,M,S)
@param stop количество стоповых бит */
/** @brief Программирует длину слова, чётность и число стоп-битов SCI. */
void RS_SetLineMode(RS_DATA *rs_arr, int bit, char parity, int stop)
{
volatile struct SCI_REGS *SciRegs;
/*
SCICCR - SCI Communication Control Register
Bit Bit Name Designation Functions
2-0 SCI CHAR2-0 SCICHAR Select the character (data) length (one to eight bits).
3 ADDR/IDLE MODE ADDRIDLE_MODE The idle-line mode (0) is usually used for normal communications because the address-bit mode adds an extra bit to the frame. The idle-line mode does not add this extra bit and is compatible with RS-232 type communications.
4 LOOP BACK ENABLE LOOPBKENA This bit enables (1) the Loop Back test mode where the Tx pin is internally connected to the Rx pin.
5 PARITY ENABLE PARITYENA Enables the parity function if set to 1, or disables the parity function if cleared to 0.
6 EVEN/ODD PARITY PARITY If parity is enabled, selects odd parity if cleared to 0 or even parity if set to 1.
7 STOP BITS STOPBITS Determines the number of stop bits transmitted-one stop bit if cleared to 0 or two stop bits if set to 1.
*/
SciRegs = rs_arr->SciRegs;
if(bit>0 && bit<9) SciRegs->SCICCR.bit.SCICHAR = bit-1;
switch(parity)
{
case 'N': SciRegs->SCICCR.bit.PARITYENA = 0;
break;
case 'O': SciRegs->SCICCR.bit.PARITYENA = 1;
SciRegs->SCICCR.bit.PARITY = 0;
break;
case 'E': SciRegs->SCICCR.bit.PARITYENA = 1;
SciRegs->SCICCR.bit.PARITY = 1;
break;
}
if (stop==1) SciRegs->SCICCR.bit.STOPBITS = 0;
if (stop==2) SciRegs->SCICCR.bit.STOPBITS = 1;
SciRegs->SCICCR.bit.LOOPBKENA = 0; //0
SciRegs->SCICCR.bit.ADDRIDLE_MODE = 0;
}
/** @brief Отмечает успешную активность порта и сбрасывает его watchdog связи. */
void clear_timer_rs_live(RS_DATA *rs_arr)
{
rs_arr->time_wait_rs_out=0;
}
/* проверка на живучесть RS */
/** @brief Увеличивает watchdog связи и фиксирует тайм-аут удалённого узла. */
void test_rs_live(RS_DATA *rs_arr)
{
/* if (rs_arr->time_wait_rs_out < RS_TIME_OUT)
rs_arr->time_wait_rs_out++;
else
{
rs_arr->time_wait_rs_out=0;
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
}*/ }