// basic protocol routines void uMCP_DataSend(bool isDTE, byte tcnt, byte rcnt, ushort rPos, ushort cnt, bool isStartTimer) { uMCP_PacketType ptype = uMCP_PacketType.uMCP_PTYPE_DTA; if (isDTE) { ptype = uMCP_PacketType.uMCP_PTYPE_DTE; } Str_WriterInit(ref ol_buffer, ref ol_cnt, UMCP_LBUFFER_SIZE); StrB_WriteByte(ref ol_buffer, ref ol_cnt, UMCP_SIGN); StrB_WriteByte(ref ol_buffer, ref ol_cnt, Convert.ToByte(ptype)); StrB_WriteByte(ref ol_buffer, ref ol_cnt, SID); StrB_WriteByte(ref ol_buffer, ref ol_cnt, TID); StrB_WriteByte(ref ol_buffer, ref ol_cnt, tcnt); StrB_WriteByte(ref ol_buffer, ref ol_cnt, rcnt); StrB_WriteByte(ref ol_buffer, ref ol_cnt, CRC8_Get(ol_buffer, 0, ol_cnt)); ushort dstart_idx = ol_cnt; StrB_WriteByte(ref ol_buffer, ref ol_cnt, (byte)cnt); int i; ushort rposc = rPos; for (i = 0; i < cnt; i++) { ol_buffer[ol_cnt++] = ih_ring[rposc]; rposc = Convert.ToUInt16((rposc + 1) % HOST_BUFFER_SIZE); } StrB_WriteByte(ref ol_buffer, ref ol_cnt, CRC8_Get(ol_buffer, dstart_idx, cnt + 1)); ol_ready = true; isTimerPendingOnTxFinish = isStartTimer; uMCP_ITimer_Init(uMCP_Timer_ID.uMCP_Timer_TX, Convert.ToUInt16(UMCP_FIXED_TX_DELAY_MS + 1000 * (int)(((float)(ol_cnt * 8)) / CFG_LINEBAUDRATE)), true); uMCP_SELECT_Set(!isDTE); }
void uMCP_CtrlSend(uMCP_PacketType ptype, byte tcnt, byte rcnt, bool isStartTimer) { Str_WriterInit(ref ol_buffer, ref ol_cnt, UMCP_LBUFFER_SIZE); StrB_WriteByte(ref ol_buffer, ref ol_cnt, UMCP_SIGN); StrB_WriteByte(ref ol_buffer, ref ol_cnt, Convert.ToByte(ptype)); StrB_WriteByte(ref ol_buffer, ref ol_cnt, SID); StrB_WriteByte(ref ol_buffer, ref ol_cnt, TID); if ((ptype == uMCP_PacketType.uMCP_PTYPE_REP) || (ptype == uMCP_PacketType.uMCP_PTYPE_ACK)) { StrB_WriteByte(ref ol_buffer, ref ol_cnt, tcnt); if (ptype == uMCP_PacketType.uMCP_PTYPE_ACK) { StrB_WriteByte(ref ol_buffer, ref ol_cnt, rcnt); } } StrB_WriteByte(ref ol_buffer, ref ol_cnt, CRC8_Get(ol_buffer, 0, ol_cnt)); ol_ready = true; isTimerPendingOnTxFinish = isStartTimer; uMCP_ITimer_Init(uMCP_Timer_ID.uMCP_Timer_TX, Convert.ToUInt16(UMCP_FIXED_TX_DELAY_MS + 1000 * (int)(((float)(ol_cnt * 8)) / CFG_LINEBAUDRATE)), true); uMCP_SELECT_Set(false); }
void uMCP_OnNewByte(DCID_Enum chID, byte c) { if (chID == DCID_Enum.HOST_DC_ID) { if (ih_Cnt <= HOST_BUFFER_SIZE) { ih_ring[ih_wPos] = c; ih_wPos = Convert.ToUInt16((ih_wPos + 1) % HOST_BUFFER_SIZE); ih_Cnt++; ih_TS = millis(); } else { //Serial.print("!TX_OVF"); TX_Overflow_Event.Rise(this, new EventArgs()); } } else if (chID == DCID_Enum.LINE_DC_ID) { if (ip_start) { if (ip_pos == 1) { ip_ahchk = CRC8_Update(ip_ahchk, c); ip_type = (uMCP_PacketType)c; if (ip_type == uMCP_PacketType.uMCP_PTYPE_INVALID) { ip_start = false; } else { ip_pos++; } } else if (ip_pos <= 3) { ip_ahchk = CRC8_Update(ip_ahchk, c); if (ip_pos == 3) { ip_tid = c; } else if (ip_pos == 2) { ip_sid = c; } ip_pos++; } else { if ((ip_type == uMCP_PacketType.uMCP_PTYPE_STR) || (ip_type == uMCP_PacketType.uMCP_PTYPE_STA)) { if (ip_ahchk == c) // CRC OK { ip_start = false; ip_ready = true; } } else { if (ip_pos == 4) { ip_tcnt = c; ip_pos++; ip_ahchk = CRC8_Update(ip_ahchk, c); } else { if (ip_type == uMCP_PacketType.uMCP_PTYPE_REP) { if (ip_ahchk == c) { ip_ready = true; } ip_start = false; } else { if (ip_pos == 5) { ip_rcnt = c; ip_pos++; ip_ahchk = CRC8_Update(ip_ahchk, c); } else { if (ip_pos == 6) // header checksum { if (ip_ahchk == c) { if (ip_type == uMCP_PacketType.uMCP_PTYPE_ACK) { ip_ready = true; ip_start = false; } else { ip_pos++; } } else { ip_start = false; } } else { if (ip_pos == 7) // dcnt { ip_dcnt = c; if (ip_dcnt >= 1) { ip_ahchk = CRC8_Update(0xff, c); ip_pos++; } else { ip_start = false; ip_ready = true; ip_type = uMCP_PacketType.uMCP_PTYPE_ACK; } } else if (ip_pos == 8 + ip_dcnt) { if (ip_ahchk == c) // data block CRC ok { ip_ready = true; } else { ip_type = uMCP_PacketType.uMCP_PTYPE_ACK; } ip_start = false; } else { ip_datablock[ip_pos - 8] = c; ip_ahchk = CRC8_Update(ip_ahchk, c); ip_pos++; } } } } } } } } else if (c == UMCP_SIGN) { ip_start = true; ip_pos = 1; ip_ahchk = CRC8_Update(0xff, UMCP_SIGN); ip_type = uMCP_PacketType.uMCP_PTYPE_INVALID; ip_dcnt = 0; } } }
void uMCP_OnIncomingPacket() { sid = ip_sid; tid = ip_tid; tcnt = ip_tcnt; rcnt = ip_rcnt; dcnt = ip_dcnt; pType = ip_type; ip_ready = false; switch (pType) { case uMCP_PacketType.uMCP_PTYPE_STR: { uMCP_SELECT_Set(true); if ((state == uMCP_State.uMCP_STATE_HALTED) || (state == uMCP_State.uMCP_STATE_ISTART)) { uMCP_STATE_Set(uMCP_State.uMCP_STATE_ASTART); uMCP_ITimer_StateSet(uMCP_Timer_ID.uMCP_Timer_TMO, false); uMCP_CtrlSend(uMCP_PacketType.uMCP_PTYPE_STA, 0, 0, true); } else if (state == uMCP_State.uMCP_STATE_ASTART) { uMCP_STATE_Set(uMCP_State.uMCP_STATE_RUNNING); uMCP_ITimer_StateSet(uMCP_Timer_ID.uMCP_Timer_TMO, false); uMCP_CtrlSend(uMCP_PacketType.uMCP_PTYPE_ACK, 0, 0, false); } else { uMCP_STATE_Set(uMCP_State.uMCP_STATE_HALTED); } break; } case uMCP_PacketType.uMCP_PTYPE_STA: { uMCP_SELECT_Set(true); if ((state == uMCP_State.uMCP_STATE_ISTART) || (state == uMCP_State.uMCP_STATE_ASTART) || (state == uMCP_State.uMCP_STATE_RUNNING)) { uMCP_STATE_Set(uMCP_State.uMCP_STATE_RUNNING); uMCP_ITimer_StateSet(uMCP_Timer_ID.uMCP_Timer_TMO, false); uMCP_CtrlSend(uMCP_PacketType.uMCP_PTYPE_ACK, 0, 0, false); } break; } case uMCP_PacketType.uMCP_PTYPE_REP: { if (state == uMCP_State.uMCP_STATE_RUNNING) { sack = true; srep = false; uMCP_SELECT_Set(true); } break; } case uMCP_PacketType.uMCP_PTYPE_ACK: { if (state == uMCP_State.uMCP_STATE_ASTART) { if (rcnt == 0) { uMCP_ITimer_StateSet(uMCP_Timer_ID.uMCP_Timer_TMO, false); uMCP_STATE_Set(uMCP_State.uMCP_STATE_RUNNING); } } else if (state == uMCP_State.uMCP_STATE_RUNNING) { uMCP_ITimer_StateSet(uMCP_Timer_ID.uMCP_Timer_TMO, false); if ((rcnt == N) || (uMCP_IsByteInRangeExclusive(A, N, rcnt))) { uMCP_AcknowledgeSentItems(rcnt); } } uMCP_SELECT_Set(true); break; } case uMCP_PacketType.uMCP_PTYPE_DTA: case uMCP_PacketType.uMCP_PTYPE_DTE: { if (state == uMCP_State.uMCP_STATE_RUNNING) { if (tcnt <= R + 1) { if (tcnt == R + 1) { R++; ff_copy_u8(ip_datablock, ref oh_buffer, dcnt); oh_cnt = dcnt; oh_ready = true; } sack = true; } iTimer_State[(int)uMCP_Timer_ID.uMCP_Timer_TMO] = false; if ((rcnt == N) || (uMCP_IsByteInRangeExclusive(A, N, rcnt))) { uMCP_AcknowledgeSentItems(rcnt); } if (pType == uMCP_PacketType.uMCP_PTYPE_DTA) { uMCP_ITimer_StateSet(uMCP_Timer_ID.uMCP_Timer_TMO, true); } uMCP_SELECT_Set(pType == uMCP_PacketType.uMCP_PTYPE_DTE); } break; } default: break; } }