feat(rs232): enable SCI-A FIFO on PM35 and preserve RS485
This commit is contained in:
@@ -21,6 +21,11 @@ static char size_cmd15=1;
|
||||
|
||||
void RS_RX_Handler(RS_DATA *rs_arr);
|
||||
void RS_TX_Handler(RS_DATA *rs_arr);
|
||||
#if RS232_USE_FIFO
|
||||
static int RS_FifoStart(RS_DATA *, unsigned int *, unsigned long, int);
|
||||
static void RS_FifoTx(RS_DATA *);
|
||||
static void RS_FifoAbort(RS_DATA *);
|
||||
#endif
|
||||
|
||||
/** Îáðàáîò÷èê ïðåðûâàíèé UART - ïðèíàòî */
|
||||
interrupt void RSA_RX_Handler(void)
|
||||
@@ -105,6 +110,24 @@ void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
|
||||
for(;;) // 'goto' ýòî íå îïåðàòîð àçûêà Ñ
|
||||
{
|
||||
#if RS232_USE_FIFO
|
||||
if (rs_arr->commnumber == COM_1) {
|
||||
unsigned int received;
|
||||
if (rs_arr->SciRegs->SCIFFRX.bit.RXFFOVF || rs_arr->SciRegs->SCIRXST.bit.RXERROR) {
|
||||
RS_FifoAbort(rs_arr); return;
|
||||
}
|
||||
if (!rs_arr->SciRegs->SCIFFRX.bit.RXFFST) {
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1;
|
||||
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
|
||||
return;
|
||||
}
|
||||
received=rs_arr->SciRegs->SCIRXBUF.all; /* one pop, data + FE/PE */
|
||||
if (received & 0xC000U) { RS_FifoAbort(rs_arr); return; }
|
||||
if (rs_arr->fifo_rx_guard) { rs_arr->fifo_rx_guard=4; continue; }
|
||||
Rc=received & 255U;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if(!rs_arr->SciRegs->SCIRXST.bit.RXRDY) // Receiver ready flag
|
||||
{
|
||||
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
|
||||
@@ -122,6 +145,8 @@ void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(rs_arr->RS_DataReady) continue; // Íå çàáðàëè äàííûå
|
||||
|
||||
if (rs_arr->RS_Flag9bit==1) // äëà RS485????????
|
||||
@@ -234,6 +259,9 @@ void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
/** Îáðàáîò÷èê ïðåðûâàíèé UART - ïîñëàíî */
|
||||
void RS_TX_Handler(RS_DATA *rs_arr)
|
||||
{
|
||||
#if RS232_USE_FIFO
|
||||
if (rs_arr->commnumber == COM_1) { RS_FifoTx(rs_arr); return; }
|
||||
#endif
|
||||
char RS_BytePtr;
|
||||
// unsigned int i;
|
||||
|
||||
@@ -278,6 +306,7 @@ void RS_TX_Handler(RS_DATA *rs_arr)
|
||||
|
||||
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
|
||||
// rs_arr->SciRegs->SCIFFTX.bit.TXINTCLR=1; // Clear INT flag
|
||||
|
||||
}
|
||||
|
||||
/** Èíèöèàëèçàöèà ìàññèâà äëèí êîìàíä */
|
||||
@@ -329,6 +358,9 @@ void RS_SetBitMode(RS_DATA *rs_arr,int n)
|
||||
@see RS_BSend, RS_TRANSMIT_INTR */
|
||||
int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf,unsigned long len)
|
||||
{
|
||||
#if RS232_USE_FIFO
|
||||
if (rs_arr->commnumber == COM_1) return RS_FifoStart(rs_arr,pBuf,len,BM_CHAR32);
|
||||
#endif
|
||||
unsigned int i;
|
||||
for (i=0; i <= 30000; i++){} /* Ïàóçà äëà PC */
|
||||
|
||||
@@ -359,11 +391,15 @@ int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf,unsigned long len)
|
||||
RS_Line_to_receive(rs_arr); /* ðåæèì ïðèåìà RS485 */
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// Ïîñûëêà áëîêà óïàêîâàííûõ áàéòîâ
|
||||
int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len)
|
||||
{
|
||||
#if RS232_USE_FIFO
|
||||
if (rs_arr->commnumber == COM_1) return RS_FifoStart(rs_arr,pBuf,len,BM_PACKED);
|
||||
#endif
|
||||
|
||||
RS_Line_to_send(rs_arr); // ðåæèì ïåðåäà÷è RS485
|
||||
|
||||
@@ -381,6 +417,7 @@ int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len)
|
||||
SCI_send(rs_arr,HIBYTE(*pBuf));// Ïåðåäàåì ïåðâûé áàéò
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/** Óñòàíàâëèâàåò ñêîðîñòü îáìåíà.
|
||||
@@ -474,7 +511,20 @@ void setup_uart(char commnumber, unsigned long speed_baud)
|
||||
SciRegs->SCICTL1.bit.TXENA=1;
|
||||
SciRegs->SCICTL1.bit.RXENA=1;
|
||||
|
||||
SciRegs->SCIFFTX.bit.SCIFFENA=0; // fifo off
|
||||
#if RS232_USE_FIFO
|
||||
if (commnumber == COM_1) {
|
||||
SciRegs->SCIFFTX.all=0xC008U; /* enhancement, reset held, TX level 8, IRQ off */
|
||||
SciRegs->SCIFFRX.all=0x0061U; /* reset held, RX level 1, IRQ on */
|
||||
SciRegs->SCIFFCT.all=0;
|
||||
SciRegs->SCIFFRX.bit.RXFFOVRCLR=1;
|
||||
SciRegs->SCIFFTX.bit.TXFFINTCLR=1;
|
||||
SciRegs->SCIFFTX.bit.TXFIFOXRESET=1;
|
||||
SciRegs->SCIFFRX.bit.RXFIFORESET=1;
|
||||
rs_arr->fifo_tx_active=rs_arr->fifo_rx_guard=0;
|
||||
rs_arr->fifo_rx_errors=rs_arr->fifo_overflows=0;
|
||||
} else
|
||||
#endif
|
||||
SciRegs->SCIFFTX.bit.SCIFFENA=0; // fifo off
|
||||
SciRegs->SCIFFRX.bit.RXFFIL=1; // Äëèíà íàèìåíüøåé êîìàíäû
|
||||
|
||||
setup_arr_cmd_length();
|
||||
@@ -547,3 +597,117 @@ void test_rs_live(RS_DATA *rs_arr)
|
||||
RS_Line_to_receive(rs_arr); // ðåæèì ïðèåìà RS485
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
}*/ }
|
||||
|
||||
#if RS232_USE_FIFO
|
||||
/* FIFO is exclusively SCI-A / RS232. SCI-B keeps the legacy path. */
|
||||
void RS_FifoWait(RS_DATA *rs_arr)
|
||||
{
|
||||
if (rs_arr->commnumber != COM_1) {
|
||||
while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }
|
||||
return;
|
||||
}
|
||||
while (rs_arr->fifo_tx_active || rs_arr->SciRegs->SCIFFTX.bit.TXFFST ||
|
||||
!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }
|
||||
}
|
||||
|
||||
static void RS_FifoTx(RS_DATA *rs_arr)
|
||||
{
|
||||
unsigned int data;
|
||||
if (!rs_arr->fifo_tx_active) {
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=0;
|
||||
} else if (rs_arr->RS_SendLen == rs_arr->RS_SLength) {
|
||||
/* Level 0 interrupt: FIFO drained, last symbol may still be shifting.
|
||||
* Do not finish on TXFFST alone. At most one symbol remains. */
|
||||
if (rs_arr->SciRegs->SCIFFTX.bit.TXFFST) {
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFINTCLR=1;
|
||||
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
|
||||
return;
|
||||
}
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=0;
|
||||
while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }
|
||||
if (rs_arr->RS_SendBlockMode == BM_CHAR32) {
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
rs_arr->flag_TIMEOUT_to_Send=false;
|
||||
}
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=0;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFOVRCLR=1;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=1;
|
||||
enableUARTInt(rs_arr);
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA=1;
|
||||
rs_arr->fifo_tx_active=0;
|
||||
} else {
|
||||
while (rs_arr->RS_SendLen < rs_arr->RS_SLength &&
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFST < 16) {
|
||||
if (rs_arr->RS_SendBlockMode == BM_CHAR32)
|
||||
data=*rs_arr->pRS_SendPtr++;
|
||||
else if (rs_arr->RS_SendLen & 1U)
|
||||
data=LOBYTE(*rs_arr->pRS_SendPtr++);
|
||||
else data=HIBYTE(*rs_arr->pRS_SendPtr);
|
||||
SCI_send(rs_arr,data);
|
||||
rs_arr->RS_SendLen++;
|
||||
}
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFIL=
|
||||
rs_arr->RS_SendLen == rs_arr->RS_SLength ? 0 : 8;
|
||||
}
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFINTCLR=1;
|
||||
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
|
||||
}
|
||||
|
||||
static int RS_FifoStart(RS_DATA *rs_arr,unsigned int *buffer,unsigned long count,int mode)
|
||||
{
|
||||
unsigned int saved;
|
||||
if (!count) return 0;
|
||||
if (!buffer) return -1;
|
||||
RS_FifoWait(rs_arr); /* before replacing the previous transfer's counters */
|
||||
saved=__disable_interrupts();
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=0;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA=0;
|
||||
enableUARTIntW(rs_arr);
|
||||
RS_SetBitMode(rs_arr,8);
|
||||
rs_arr->pRS_SendPtr=buffer;
|
||||
rs_arr->RS_SLength=count;
|
||||
rs_arr->RS_SendLen=0;
|
||||
rs_arr->RS_SendBlockMode=mode;
|
||||
rs_arr->fifo_tx_active=1;
|
||||
RS_FifoTx(rs_arr); /* prime before enabling a possibly immediate TX IRQ */
|
||||
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=1;
|
||||
__restore_interrupts(saved);
|
||||
if (count == 1 && mode == BM_CHAR32) RS_FifoWait(rs_arr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void RS_FifoAbort(RS_DATA *rs_arr)
|
||||
{
|
||||
rs_arr->fifo_rx_errors++;
|
||||
if (rs_arr->SciRegs->SCIFFRX.bit.RXFFOVF) rs_arr->fifo_overflows++;
|
||||
rs_arr->RS_DataReady=0; rs_arr->BS_LoadOK=0;
|
||||
rs_arr->RS_PrevCmd=0; rs_arr->RS_Cmd=0;
|
||||
rs_arr->RS_Flag9bit=0; rs_arr->RS_FlagSkiping=1;
|
||||
rs_arr->fifo_rx_guard=4;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=0;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFOVRCLR=1;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1;
|
||||
if (rs_arr->SciRegs->SCIRXST.bit.RXERROR) {
|
||||
rs_arr->SciRegs->SCICTL1.bit.SWRESET=0;
|
||||
rs_arr->SciRegs->SCICTL1.bit.SWRESET=1;
|
||||
}
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=1;
|
||||
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
|
||||
}
|
||||
|
||||
void RS_FifoTick1ms(void)
|
||||
{
|
||||
unsigned int saved=__disable_interrupts();
|
||||
RS_DATA *p=&rs_a;
|
||||
if (p->SciRegs && p->fifo_rx_guard) {
|
||||
if (p->SciRegs->SCIFFRX.bit.RXFFST) p->fifo_rx_guard=4;
|
||||
else if (--p->fifo_rx_guard == 0) {
|
||||
p->RS_HeaderCnt=0;p->RS_RecvLen=0;
|
||||
p->RS_FlagBegin=1;p->RS_FlagSkiping=0;
|
||||
RS_SetBitMode(p,9); /* fresh address after 3..4 ms of idle */
|
||||
}
|
||||
}
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user