📄 mac_rx.s51
字号:
CFI ?RET_LOW load(1, XDATA, add(CFA_XSP16, literal(-5)))
CFI R7 load(1, XDATA, add(CFA_XSP16, literal(-6)))
CFI V3 load(1, XDATA, add(CFA_XSP16, literal(-7)))
CFI V2 load(1, XDATA, add(CFA_XSP16, literal(-8)))
CFI V1 load(1, XDATA, add(CFA_XSP16, literal(-9)))
CFI V0 load(1, XDATA, add(CFA_XSP16, literal(-10)))
CFI VB load(1, XDATA, add(CFA_XSP16, literal(-11)))
CFI R6 load(1, XDATA, add(CFA_XSP16, literal(-12)))
CFI CFA_SP SP+0
CFI CFA_XSP16 add(XSP16, 12)
; Saved register size: 12
; Auto size: 2
MOV A,#-0x2
LCALL ?ALLOC_XSTACK8
CFI CFA_XSP16 add(XSP16, 14)
// 364 uint8 addrLen;
// 365 uint8 ackWithPending;
// 366 uint8 dstAddrMode;
// 367 uint8 srcAddrMode;
// 368
// 369 MAC_ASSERT(!macRxActive); /* receive on top of receive */
MOV DPTR,#macRxActive
MOVX A,@DPTR
JZ ??rxStartIsr_1
; Setup parameters for call to function halAssertHandler
MOV DPTR,#(halAssertHandler & 0xffff)
MOV A,#((halAssertHandler >> 16) & 0xff)
LCALL ?BCALL ; Banked call to: DPTR()
// 370
// 371 /* indicate rx is active */
// 372 macRxActive = MAC_RX_ACTIVE_STARTED;
??rxStartIsr_1:
MOV A,#-0x7f
MOV DPTR,#macRxActive
MOVX @DPTR,A
// 373
// 374 /*
// 375 * For bullet proof functionality, need to see if the receiver was just turned off.
// 376 * The logic to request turning off the receiver, disables interrupts and then checks
// 377 * the value of macRxActive. If it is TRUE, the receiver will not be turned off.
// 378 *
// 379 * There is a small hole though. It's possible to attempt turning off the receiver
// 380 * in the window from when the receive interrupt fires and the point where macRxActive
// 381 * is set to TRUE. To plug this hole, the on/off status must be tested *after*
// 382 * macRxActive has been set. If the receiver is off at this point, there is nothing
// 383 * in the RX fifo and the receive is simply aborted.
// 384 *
// 385 * Also, there are some considerations in case a hard disable just happened. Usually,
// 386 * the receiver will just be off at this point after a hard disable. The check described
// 387 * above will account for this case too. However, if a hard disable were immediately
// 388 * followed by an enable, the receiver would be on. To catch this case, the receive
// 389 * FIFO is also tested to see if it is empty. Recovery is identical to the other cases.
// 390 */
// 391 if (!macRxOnFlag || MAC_RADIO_RX_FIFO_IS_EMPTY())
MOV DPTR,#macRxOnFlag
MOVX A,@DPTR
JZ ??rxStartIsr_2
MOV DPTR,#-0x209e
MOVX A,@DPTR
MOV C,0xE0 /* A */.3
JC ??rxStartIsr_3
MOVX A,@DPTR
MOV C,0xE0 /* A */.2
JC ??rxStartIsr_3
// 392 {
// 393 /* reset active flag */
// 394 macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
??rxStartIsr_2:
CLR A
MOV DPTR,#macRxActive
MOVX @DPTR,A
// 395
// 396 /*
// 397 * To be absolutely bulletproof, must make sure no transmit queue'ed up during
// 398 * the tiny, tiny window when macRxActive was not zero.
// 399 */
// 400 rxPostRxUpdates();
; Setup parameters for call to function rxPostRxUpdates
MOV DPTR,#(??rxPostRxUpdates & 0xffff)
MOV A,#((??rxPostRxUpdates >> 16) & 0xff)
??rxStartIsr_4:
LCALL ?BCALL ; Banked call to: DPTR()
// 401
// 402 /* return immediately from here */
// 403 return;
LJMP ??rxStartIsr_5 & 0xFFFF
// 404 }
// 405
// 406 /*
// 407 * If interrupts are held off for too long it's possible the previous "transmit done"
// 408 * callback is pending. If this is the case, it needs to be completed before
// 409 * continuing with the receive logic.
// 410 */
// 411 MAC_RADIO_FORCE_TX_DONE_IF_PENDING();
??rxStartIsr_3:
; Setup parameters for call to function macCspForceTxDoneIfPending
MOV DPTR,#(macCspForceTxDoneIfPending & 0xffff)
MOV A,#((macCspForceTxDoneIfPending >> 16) & 0xff)
LCALL ?BCALL ; Banked call to: DPTR()
// 412
// 413 /*
// 414 * It's possible receive logic is still waiting for confirmation of an ACK that went out
// 415 * for the previous receive. This is OK but the callback needs to be canceled at this point.
// 416 * That callback execute receive cleanup logic that will run at the completion
// 417 * of *this* receive. Also, it is important the flag for the outgoing ACK to be cleared.
// 418 */
// 419 MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
; Setup parameters for call to function macMcuAndRFIM
MOV R1,#-0x11
MOV DPTR,#(macMcuAndRFIM & 0xffff)
MOV A,#((macMcuAndRFIM >> 16) & 0xff)
LCALL ?BCALL ; Banked call to: DPTR()
// 420 macRxOutgoingAckFlag = 0;
CLR A
MOV DPTR,#macRxOutgoingAckFlag
MOVX @DPTR,A
// 421
// 422 /*
// 423 * Make a module-local copy of macRxFilter. This prevents the selected
// 424 * filter from changing in the middle of a receive.
// 425 */
// 426 rxFilter = macRxFilter;
MOV DPTR,#macRxFilter
MOVX A,@DPTR
MOV DPTR,#??rxFilter
MOVX @DPTR,A
// 427
// 428 /*-------------------------------------------------------------------------------
// 429 * Read initial frame information from FIFO.
// 430 *
// 431 * This code is not triggered until the following are in the RX FIFO:
// 432 * frame length - one byte containing length of MAC frame (excludes this field)
// 433 * frame control field - two bytes defining frame type, addressing fields, control flags
// 434 * sequence number - one byte unique sequence identifier
// 435 * additional two bytes - these bytes are available in case the received frame is an ACK,
// 436 * if so, the frame can be verified and responded to immediately,
// 437 * if not an ACK, these bytes will be processed normally
// 438 */
// 439
// 440 /* read frame length, frame control field, and sequence number from FIFO */
// 441 MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_PHY_PHR_LEN + MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN);
; Setup parameters for call to function macMemReadRxFifo
MOV R1,#0x4
MOV R2,#(??rxBuf & 0xff)
MOV R3,#((??rxBuf >> 8) & 0xff)
MOV DPTR,#(macMemReadRxFifo & 0xffff)
MOV A,#((macMemReadRxFifo >> 16) & 0xff)
LCALL ?BCALL ; Banked call to: DPTR()
// 442
// 443 /* bytes to read from FIFO equals frame length minus length of MHR fields just read from FIFO */
// 444 rxUnreadLen = (rxBuf[0] & PHY_PACKET_SIZE_MASK) - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN;
MOV DPTR,#??rxBuf
MOVX A,@DPTR
ANL A,#0x7f
ADD A,#-0x3
MOV DPTR,#??rxUnreadLen
MOVX @DPTR,A
// 445
// 446 /*
// 447 * Workaround for chip bug. The receive buffer can sometimes be corrupted by hardware.
// 448 * This usually occurs under heavy traffic. If a corrupted receive buffer is detected
// 449 * the entire receive buffer is flushed.
// 450 *
// 451 * In the case that this workaround is not needed, an assert is used to make sure the
// 452 * receive length field is not corrupted. This is important because a corrupted receive
// 453 * length field is utterly fatal and, if not caught here, extremely hard to track down.
// 454 */
// 455 #ifdef MAC_RADIO_RXBUFF_CHIP_BUG
// 456 if ((rxUnreadLen > (MAC_A_MAX_PHY_PACKET_SIZE - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN)) ||
// 457 (MAC_FRAME_TYPE(&rxBuf[1]) > MAC_FRAME_TYPE_MAX_VALID))
CLR C
SUBB A,#0x7d
JNC ??rxStartIsr_6
MOV DPTR,#(??rxBuf + 1)
MOVX A,@DPTR
ANL A,#0x7
CLR C
SUBB A,#0x4
JC ??rxStartIsr_7
// 458 {
// 459 MAC_RADIO_FLUSH_RX_FIFO();
??rxStartIsr_6:
MOV 0xe1,#-0x1a
MOV 0xe1,#-0x1a
SJMP ??rxStartIsr_8
// 460 rxDone();
// 461 return;
// 462 }
// 463 #else
// 464 /* radio supplied a corrupted receive buffer length */
// 465 MAC_ASSERT(rxUnreadLen <= (MAC_A_MAX_PHY_PACKET_SIZE - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN));
// 466 #endif
// 467
// 468
// 469
// 470 /*-------------------------------------------------------------------------------
// 471 * Process ACKs.
// 472 *
// 473 * If this frame is an ACK, process it immediately and exit from here.
// 474 * If this frame is not an ACK and transmit is listening for an ACK, let
// 475 * the transmit logic know an non-ACK was received so transmit can complete.
// 476 *
// 477 * In promiscuous mode ACKs are treated like any other frame.
// 478 */
// 479 if ((MAC_FRAME_TYPE(&rxBuf[1]) == MAC_FRAME_TYPE_ACK) && (rxPromiscuousMode == PROMISCUOUS_MODE_OFF))
??rxStartIsr_7:
MOVX A,@DPTR
ANL A,#0x7
XRL A,#0x2
JNZ ??rxStartIsr_9
MOV DPTR,#??rxPromiscuousMode
MOVX A,@DPTR
JNZ ??rxStartIsr_9
// 480 {
// 481 uint8 fcsBuf[MAC_FCF_FIELD_LEN];
// 482 /*
// 483 * There are guaranteed to be two unread bytes in the FIFO. By defintion, for ACK frames
// 484 * these two bytes will be the FCS.
// 485 */
// 486
// 487 /* read FCS from FIFO (threshold set so bytes are guaranteed to be there) */
// 488 MAC_RADIO_READ_RX_FIFO(fcsBuf, MAC_FCS_FIELD_LEN);
; Setup parameters for call to function macMemReadRxFifo
MOV R1,#0x2
MOV DPL,?XSP + 0
MOV DPH,?XSP + 1
MOV R2,DPL
MOV R3,DPH
MOV DPTR,#(macMemReadRxFifo & 0xffff)
MOV A,#((macMemReadRxFifo >> 16) & 0xff)
LCALL ?BCALL ; Banked call to: DPTR()
// 489
// 490 /* see if transmit is listening for an ACK */
// 491 if (macTxActive == MAC_TX_ACTIVE_LISTEN_FOR_ACK)
MOV DPTR,#macTxActive
MOVX A,@DPTR
XRL A,#0x85
JNZ ??rxStartIsr_8
// 492 {
// 493 /*
// 494 * An ACK was received so transmit logic needs to know. If the FCS failed,
// 495 * the transmit logic still needs to know. In that case, treat the frame
// 496 * as a non-ACK to complete the active transmit.
// 497 */
// 498 if (PROPRIETARY_FCS_CRC_OK(fcsBuf))
MOV A,#0x1
LCALL ?XSTACK_DISP0_8
MOVX A,@DPTR
MOV C,0xE0 /* A */.7
JNC ??rxStartIsr_10
// 499 {
// 500 /* call transmit logic to indicate ACK was received */
// 501 macTxAckReceivedCallback(MAC_SEQ_NUMBER(&rxBuf[1]), MAC_FRAME_PENDING(&rxBuf[1]));
; Setup parameters for call to function macTxAckReceivedCallback
MOV DPTR,#(??rxBuf + 1)
MOVX A,@DPTR
ANL A,#0x10
MOV R2,A
MOV DPTR,#(??rxBuf + 3)
MOVX A,@DPTR
MOV R1,A
MOV DPTR,#(macTxAckReceivedCallback & 0xffff)
MOV A,#((macTxAckReceivedCallback >> 16) & 0xff)
SJMP ??rxStartIsr_11
// 502 }
// 503 else
// 504 {
// 505 macTxAckNotReceivedCallback();
??rxStartIsr_10:
; Setup parameters for call to function macTxAckNotReceivedCallback
MOV DPTR,#(macTxAckNotReceivedCallback & 0xffff)
MOV A,#((macTxAckNotReceivedCallback >> 16) & 0xff)
??rxStartIsr_11:
LCALL ?BCALL ; Banked call to: DPTR()
// 506 }
// 507 }
// 508
// 509 /* receive is done, exit from here */
// 510 rxDone();
??rxStartIsr_8:
; Setup parameters for call to function rxDone
MOV DPTR,#(??rxDone & 0xffff)
MOV A,#((??rxDone >> 16) & 0xff)
LJMP ??rxStartIsr_4 & 0xFFFF
// 511 return;
// 512 }
// 513 else if (macTxActive == MAC_TX_ACTIVE_LISTEN_FOR_ACK)
??rxStartIsr_9:
MOV DPTR,#macTxActive
MOVX A,@DPTR
XRL A,#0x85
JNZ ??rxStartIsr_12
// 514 {
// 515 macTxAckNotReceivedCallback();
; Setup parameters for call to function macTxAckNotReceivedCallback
MOV DPTR,#(macTxAckNotReceivedCallback & 0xffff)
MOV A,#((macTxAckNotReceivedCallback >> 16) & 0xff)
LCALL ?BCALL ; Banked call to: DPTR()
// 516 }
// 517
// 518 /*-------------------------------------------------------------------------------
// 519 * Apply filtering.
// 520 *
// 521 * For efficiency, see if filtering is even 'on' before processing. Also test
// 522 * to make sure promiscuous mode is disabled. If promiscuous mode is enabled,
// 523 * do not apply filtering.
// 524 */
// 525 if ((rxFilter != RX_FILTER_OFF) && !rxPromiscuousMode)
??rxStartIsr_12:
MOV DPTR,#??rxFilter
MOVX A,@DPTR
JZ ??rxStartIsr_13
MOV DPTR,#??rxPromiscuousMode
MOVX A,@DPTR
JNZ ??rxStartIsr_13
// 526 {
// 527 if (/* filter all frames */
// 528 (rxFilter == RX_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -