void main() { /* configures the function of the A/D port pins * (ports A and E to digital I/Os) */ ADCON1=7; TRISD=0x0f; /* 00001111 -> RD4:RD7 as outputs */ TRISE=3; /* 111 -> RE0:RE2 outputs */ PORTE=4; PORTD=0; /* set the activity LED bit as an output */ TRISC&=0xf7; /* make sure LED is off */ LEDPORT|=0x08; /* then flash it 3 times */ LED_flash(3); /* initialise USART interrupts */ SerIntInit(); /* enter main program loop */ while(1) { /* There's a packet waiting in the buffer.. IP layer * flag is set so we can return up the stack, rather than processing * the packet within the interrupt routine */ if (rxstate == RXDONE) { /* call on the IP layer to process awaiting packet */ ip_receive(); /* serial line IDLE again */ rxstate=RXIDLE; /* packet has been sent */ txpos=0; } /* Interrrupt routine has been trggered since last here, * there is at least one byte waiting in the USART receive * buffer - call on the SLIP layer to process and add to * stack buffer */ if (GetRxSize()) slip_recv(); /* ensure activity LED is off */ LEDPORT|=0x08; /* TCP counter, used for Initial Sequence Numbers */ if (tcpcounter == 2147483646) { tcpcounter=0; } tcpcounter++; } }
void S1_Interrupt(void) { UBYTE int_kind; UBYTE int_factor; UBYTE status; UWORD rtn; rtn = 0; int_kind = S1_GetInterruptKind(); /* 割込み種別を得る */ switch (ModemBlock.Mode) { /* 交信モード */ case MODE_RX_G3: if (!(int_kind & S1_REG_BIT_IRRX_SCI)) { /* SCI受信部の割り込みでない場合 */ break; } int_factor = S1_SCI_GetIntFactor(); /* 割込み要因を得る */ status = S1_SCI_GetRxStatus(); /* 受信ステータスを得る */ if (int_factor & S1_REG_BIT_SCI_OVERQ) { /* オーバーランエラーの場合 */ SYB_MaintenanceSwitch[MNT_SW_C1] |= MDM_RX_BUFFER_OVERRUN; /* メンテナンススイッチに通知 */ } S1_SCI_ClearRxStatus(); /* 受信ステイタスクリア */ break; case MODE_TX_G3: if (!(int_kind & S1_REG_BIT_IRTX_SCI)) { /* SCI送信部の割り込みでない場合 */ break; } int_factor = S1_SCI_GetIntFactor(); /* 割込み要因を得る */ status = S1_SCI_GetTxStatus(); /* 受信ステータスを得る */ if (int_factor & S1_REG_BIT_SCI_UNERQ) { /* アンダーランエラーの場合 */ } if (int_factor & S1_REG_BIT_SCI_TXENDRQ) { /* TxEND(送信すべきデータがない)の場合 */ } S1_SCI_ClearTxStatus(); /* 送信ステイタスクリア */ break; case MODE_RX_ECM: if (!(int_kind & S1_REG_BIT_IRRX_HDLC)) { /* HDLC受信部の割り込みでない場合 */ break; } status = S1_HDLC_GetRxStatus(); /* 受信ステータスを得る */ if (status & S1_REG_BIT_HDLC_EOF) { /* フレーム終了 */ if ((MDM_DmaStart != MDM_DMA_MASK) && !(status & S1_REG_BIT_HDLC_CRC)) { /** FCS計算結果OKの時 *//* For Debug By O.K Feb.16,1996 */ /* ここに来るまでに次のフレームの先頭データを受信したときの処理を追加。 Changed by H.Kubo 1999/01/26 */ /* DMA(DTC) はここで止めないといけない。カウンタを読んでからマスクするまでの間に次の DREQ が来たら ** 終了割り込みがかかることがある。 ** by H.Kubo 1999/01/26 */ DMA_RequestMask(DMA_CH_RX); GetRxSize(ModemControl.WritePoint); /** フレームサイズ取得 */ ModemControl.UsedCount++; ModemRxStatus &= ~(1<<ModemControl.WritePoint); /** フレーム受信上位通知処理 */ /* フレーム最後のフラグを受信してからここに来るまでの間に次のフレームの先頭を受信していたら、 ** 次のフレームの先頭は次のモデムバッファにコピーして残りのデータの受信を始めます。 ** そうでなければ、次のフレームは普通に次のモデムバッファの先頭から受信し始めます。 ** by H.Kubo 1999/01/26 */ if ((MDM_RxSize[ModemControl.WritePoint] == (FcomEcmSize+MODEM_FRAMING_CODE_LENGTH+1)) && (MDM_ModemBuffer[ModemControl.WritePoint][FcomEcmSize+MODEM_FRAMING_CODE_LENGTH] == 0xff)) { /* 次のアドレスフィールドのデータが末尾にある場合 */ MDM_ModemBuffer[ModemControl.WritePoint][FcomEcmSize+MODEM_FRAMING_CODE_LENGTH] = 0x0; MDM_RxSize[ModemControl.WritePoint] -= 1; /* 次のモデムバッファに移した分だけ引き算します。 */ NextMdmBufWritePointSetExtRom(); MDM_ModemBuffer[ModemControl.WritePoint][0] = 0xff; SelectDreqDirection(RX_DMA); DMA_RestartDMAU(DMA_CH_RX, DMA_IO_TO_MEMORY, (FcomEcmSize+MODEM_FRAMING_CODE_LENGTH), (UDWORD)&MDM_ModemBuffer[ModemControl.WritePoint][1]); } else { NextMdmBufWritePointSetExtRom(); SelectDreqDirection(RX_DMA); DMA_RestartDMAU(DMA_CH_RX, DMA_IO_TO_MEMORY, (FcomEcmSize+MODEM_FRAMING_CODE_LENGTH+1), (UDWORD)&MDM_ModemBuffer[ModemControl.WritePoint][0]); } MDM_DmaStart = MDM_DMA_GO; } else { DMA_RequestMask(DMA_CH_RX);/* 1st argument MASTER_DMAU deleted by H. Kubo 1997/06/24 */ SelectDreqDirection(RX_DMA); DMA_RestartDMAU(DMA_CH_RX, DMA_IO_TO_MEMORY, (FcomEcmSize+MODEM_FRAMING_CODE_LENGTH+1), (UDWORD)&MDM_ModemBuffer[ModemControl.WritePoint][0]);/** By O.K Jan.K Jan.23,1996 **/ MDM_DmaStart = MDM_DMA_GO; } } else if (status & (S1_REG_BIT_HDLC_CRC | S1_REG_BIT_HDLC_OER | S1_REG_BIT_HDLC_SFER | S1_REG_BIT_HDLC_ADET)) { DMA_RequestMask(DMA_CH_RX); SelectDreqDirection(RX_DMA); DMA_RestartDMAU(DMA_CH_RX, DMA_IO_TO_MEMORY, (FcomEcmSize+MODEM_FRAMING_CODE_LENGTH+1), (UDWORD)&MDM_ModemBuffer[ModemControl.WritePoint][0]); /* DMA_RestartDMAU(DMA_CH_RX, DMA_IO_TO_MEMORY, (FcomEcmSize + 4), (UDWORD)&MDM_ModemBuffer[ModemControl.WritePoint][0]); */ MDM_DmaStart = MDM_DMA_GO; if (status & S1_REG_BIT_HDLC_OER) { SYB_MaintenanceSwitch[MNT_SW_C1] |= MDM_RX_BUFFER_OVERRUN; } } S1_HDLC_ClearRxStatus(); /* 受信ステータスクリア */ if ((MDM_DmaStart == MDM_DMA_GO) && (inp(MDM_REG_1E_PORT) & IO_BIT_RDBIE)) { MDM_SetIO(POS_RDBIE,OFF); MDM_DmaStart = MDM_DMA_CONTINUE; } break; case MODE_TX_ECM: if (!(int_kind & S1_REG_BIT_IRTX_HDLC)) { /* HDLC送信部の割り込みでない場合 */ break; } status = S1_HDLC_GetTxStatus(); #if 0 if (status & S1_REG_BIT_HDLC_TXEND) { if (ModemControl.Status & STAT_ALSENT) { /** 送出データがセット済みの時 */ ModemControl.Status &= (~STAT_ALSENT); /** FCS割り込み待ち解除 */ ModemInterruptFlag = 1; /** モデム割り込み発生フラグセット */ MDM_SetIO(POS_TEOF,OFF); rtn |= MDM_EVT_TX_FCS_COMPLETE_BIT; /* V21ch2 フラグ(7E) 検出 */ } S1_HDLC_ClearTxStatus(S1_REG_BIT_HDLC_TXEND); } if ((MDM_DmaStart == MDM_DMA_GO) && (inp(MDM_REG_1E_PORT) & IO_BIT_RDBIE)) { MDM_SetIO(POS_RDBIE,OFF); MDM_DmaStart = MDM_DMA_CONTINUE; } #endif break; case 0: /* モデムクローズした後の割込み(なぜか入ることがある) */ if (int_kind & S1_REG_BIT_IRRX_HDLC) { /* HDLC受信部の割り込み */ status = S1_HDLC_GetRxStatus(); /* 受信ステータスを得る */ S1_HDLC_ClearRxStatus(); /* 受信ステータスクリア */ } if (int_kind & S1_REG_BIT_IRTX_HDLC) { /* HDLC送信部の割り込み */ status = S1_HDLC_GetTxStatus(); /* 送信ステータスを得る */ S1_HDLC_ClearTxStatus(status); /* 送信ステータスクリア */ } if (int_kind & S1_REG_BIT_IRRX_SCI) { /* SCI受信部の割り込み */ status = S1_SCI_GetRxStatus(); /* 受信ステータスを得る */ S1_SCI_ClearRxStatus(); /* 受信ステータスクリア */ } if (int_kind & S1_REG_BIT_IRTX_SCI) { /* SCI送信部の割り込み */ status = S1_SCI_GetTxStatus(); /* 送信ステータスを得る */ S1_SCI_ClearTxStatus(); /* 送信ステータスクリア */ } break; default: break; } S1_ClearInterrupt(); /* 割込みクリア */ if (rtn != 0 ) { if ( (rtn & MDM_EVT_ATV25_DETECT_BIT) != 0 ) { idet_evt(EVT_MDM_ATV25); } if ( (rtn & MDM_EVT_MDM_PNSUC_BIT) != 0 ) { idet_evt(EVT_MDM_PNSUC); } if ( (rtn & MDM_EVT_TX_FCS_COMPLETE_BIT) != 0 ) { idet_evt(EVT_TX_FCS_COMPLETE); } if ( (rtn & MDM_EVT_RX_FLG_DETECT_BIT) != 0 ) { idet_evt(EVT_RX_FLG_DETECT); } if ( (rtn & MDM_EVT_RX_RDBF_BIT) != 0 ) { idet_evt(EVT_MDM_RX_NEW_DATA); } } }
/********************************************************************************* * Reads a byte from the USART buffer, demultiplexing it according * to the SLIP RFC. This function will not return until the USART buffer * is empty. *******************************************************************************/ void slip_recv() { BYTE c; /* toggle activity LED */ LEDPORT^=(1<<LEDBIT); /* line is idle, this is the first byte * if it's not an END, then it must be noise */ if (rxstate == RXIDLE) { /* read the first byte */ c = WaitRx(); /* noise - ignore */ if (c != END) return; /* set state flag to indicate * reception is in the middle of a packet */ rxstate = RXACTIVE; } while (1) { /* zero bytes in buffer, don't really want to 'Wait' for a byte to * appear if we could be doing something else instead */ if (!GetRxSize()) return; /* get next byte from RX buffer */ c = WaitRx(); switch(c) { case END: /* got an END byte while in the middle of a packet - must * be the end */ if (received) { rxstate = RXDONE; received=0; return; } else { break; } case ESC: /* need to know the next byte to decide what * the original byte was */ c = WaitRx(); switch(c) { case ESC_END: c = END; break; case ESC_ESC: c = ESC; break; } default: /* the packet is too long */ if (received == RXMAXLEN) { /* wait for END byte * don't do anything with the data we receive now */ while (WaitRx() != END) { } /* line goes idle again - ready for next packet */ received = 0; rxstate = RXDONE; return; } else { /* place received byte in memory buffer */ rxbuff[received++] = c; } break; } } }