/******************************************************************************* Function: TCPIP_MAC_EVENT_RESULT MRF24W_MACEventSetNotifyHandler(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, pMacEventF eventHandler, void* hParam) Summary: Sets a new event notification handler. Description: This function sets a new event notification handler. This is a handler specified by the user of the stack. The caller can use the handler to be notified of MAC events. Whenever a notification occurs the passed events have to be eventually processed: - Stack should process the TCPIP_EV_RX_PKTPEND, TCPIP_EV_TX_DONE events - Process the specific (error) condition - Acknowledge the events by calling MRF24W_MACEventAck() so that they can be re-enabled. Precondition: TCPIPInit should have been called. tcpEvGroup valid value Parameters: hMac - parameter identifying the intended MAC tcpEvGroup - group of events the notification handler refers to eventHandler - the event notification handler Returns: TCPIP_MAC_EVRES_OK if operation succeeded, an error code otherwise Example: <code> MRF24W_MACEventSetNotifyHandler( hMac, TCPIP_MAC_EVGROUP_ALL, myEventHandler, myParam ); </code> Remarks: The notification handler will be called from the ISR which detects the corresponding event. The event notification handler has to be kept as short as possible and non-blocking. Mainly useful for RTOS integration where this handler will wake-up a thread that waits for a MAC event to occur. The event notification system also enables the user of the TCPIP stack to call into the stack for processing only when there are relevant events rather than being forced to periodically call from within a loop at unknown moments. Without a notification handler the stack user can still call MRF24W_MACEventGetPending() to see if processing by the stack needed. This is a default way of adding interrupt processing to the stack. A separate ISR to catch the Ethernet MAC events and process accordingly could be added. All the groups specified in the TCPIP_MAC_EVENT_GROUP enumeration is supported. However, once a handler for TCPIP_MAC_EVGROUP_ALL is registered all event processing will be reported using this global handler. Use 0 to remove the handler for a specific event group. Not multi-threaded safe accross different TCPIP_MAC_EVENT_GROUP groups. *****************************************************************************/ TCPIP_MAC_EVENT_RESULT MRF24W_MACEventSetNotifyHandler(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, pMacEventF eventHandler, void* hParam) { if(tcpEvGroup != TCPIP_MAC_EVGROUP_ALL) { return TCPIP_MAC_EVRES_GROUP_ERR; } int rfILev; if(_mrfGroupDcpt._mrfEnabledEvents) { // already have some active rfILev = SYS_INT_SourceDisable(MRFWB0M_INT_SOURCE); // stop ints for a while _mrfGroupDcpt._mrfNotifyFnc = eventHandler; // set new handler _mrfGroupDcpt._mrfNotifyParam = hParam; SYS_INT_SourceStatusClear(MRFWB0M_INT_SOURCE); SYS_INT_SourceRestore(MRFWB0M_INT_SOURCE, rfILev); // re-enable } else { _mrfGroupDcpt._mrfNotifyFnc = eventHandler; // set new handler _mrfGroupDcpt._mrfNotifyParam = hParam; } return TCPIP_MAC_EVRES_OK; }
/******************************************************************************* Function: TCPIP_MAC_EVENT_RESULT PIC32MACEventAck(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, TCPIP_EVENT tcpAckEv) Summary: Acknowledges and re-enables processed events. Description: This function acknowledges and re-enables processed events. Multiple events can be orr-ed together as they are processed together. The events acknowledged by this function should be the events that have been retrieved from the stack by calling PIC32MACEventGetPending() or have been passed to the user by the stack using the notification handler (PIC32MACEventSetNotifyHandler()) and have been processed and have to be re-enabled. Precondition: TCPIPInit should have been called. tcpEvGroup, tcpAckEv valid values Parameters: hMac - parameter identifying the intended MAC tcpEvGroup - group of events the acknowledge refers to tcpipEvents - the events that the user processed and need to be re-enabled Returns: TCPIP_MAC_EVRES_ACK_OK if events acknowledged TCPIP_MAC_EVRES_ACK_NONE if no events to be acknowledged an error code otherwise Example: <code> PIC32MACEventAck( hMac, TCPIP_MAC_EVGROUP_ALL, stackNewEvents ); </code> Remarks: All events should be acknowledged, in order to be re-enabled. Some events are fatal errors and should not be acknowledged (TCPIP_EV_RX_BUSERR, TCPIP_EV_TX_BUSERR). Stack re-initialization is needed under such circumstances. Some events are just system/application behavior and they are intended only as simple info (TCPIP_EV_RX_OVFLOW, TCPIP_EV_RX_BUFNA, TCPIP_EV_TX_ABORT, TCPIP_EV_RX_ACT, TCPIP_EV_RX_DONE). The TCPIP_EV_RX_FWMARK and TCPIP_EV_RX_EWMARK events are part of the normal flow control operation (if auto flow control was enabled). They should be enabled alternatively, if needed. The events are persistent. They shouldn't be re-enabled unless they have been processed and the condition that generated them was removed. Re-enabling them immediately without proper processing will have dramatic effects on system performance. Not multi-threaded safe accross different TCPIP_MAC_EVENT_GROUP groups. *****************************************************************************/ TCPIP_MAC_EVENT_RESULT PIC32MACEventAck(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, TCPIP_EVENT tcpAckEv) { int ethILev; PIC32_EMB_MAC_DCPT* pMacD = (PIC32_EMB_MAC_DCPT*)hMac; PIC32_EV_GROUP_DCPT* pDcpt = pMacD->mData._pic32_ev_group_dcpt+tcpEvGroup; tcpAckEv &= pDcpt->_TcpGroupEventsMask; if(pDcpt->_TcpEnabledEvents != 0) { // already have some active eEthEvents ethAckEv; ethAckEv=_XtlEventsTcp2Eth(tcpAckEv); ethILev = SYS_INT_SourceDisable(pMacD->mData._macIntSrc); // stop ints for a while pDcpt->_TcpPendingEvents &= ~tcpAckEv; // no longer pending pDcpt->_EthPendingEvents &= ~ethAckEv; // no longer pending EthEventsClr(ethAckEv); // clear the old pending ones EthEventsEnableSet(ethAckEv); // re-enable the ack ones SYS_INT_SourceRestore(pMacD->mData._macIntSrc, ethILev); // re-enable return TCPIP_MAC_EVRES_ACK_OK; } return TCPIP_MAC_EVRES_ACK_NONE; }
/******************************************************************************* Function: TCPIP_MAC_EVENT_RESULT PIC32MACEventClearNotifyEvents(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, TCPIP_EVENT tcpipEvents) Summary: Removes events from the list of the enabled ones. Description: This function removes from the enabled events. Multiple events can be orr-ed together. All events that are set will be removed from the notification process. The other events will not ne touched. Precondition: TCPIPInit should have been called. tcpEvGroup, tcpClrEv valid values Parameters: hMac - parameter identifying the intended MAC tcpEvGroup - group of events the notification refers to tcpipEvents - events the user of the stack wants to remove from notification Returns: TCPIP_MAC_EVRES_OK if operation succeeded, an error code otherwise Example: <code> PIC32MACEventClearNotifyEvents( hMac, TCPIP_MAC_EVGROUP_ALL, TCPIP_EV_RX_OVFLOW | TCPIP_EV_RX_BUFNA ); </code> Remarks: If the notification events are nill (accross all groups) the interrupt processing will be disabled. Otherwise the event notification will be enabled and the interrupts relating to the requested events will be enabled. Not multi-threaded safe accross different TCPIP_MAC_EVENT_GROUP groups. *****************************************************************************/ TCPIP_MAC_EVENT_RESULT PIC32MACEventClearNotifyEvents(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, TCPIP_EVENT tcpClrEv) { eEthEvents ethClrEvents; int ethILev = 0; PIC32_EMB_MAC_DCPT* pMacD = (PIC32_EMB_MAC_DCPT*)hMac; PIC32_EV_GROUP_DCPT* pDcpt = pMacD->mData._pic32_ev_group_dcpt+tcpEvGroup; tcpClrEv &= pDcpt->_TcpGroupEventsMask; tcpClrEv &= pDcpt->_TcpEnabledEvents; // keep just the enabled ones ethClrEvents = _XtlEventsTcp2Eth(tcpClrEv); if(pDcpt->_TcpEnabledEvents != 0) { // already have some active ethILev = SYS_INT_SourceDisable(pMacD->mData._macIntSrc); // stop ints for a while } pDcpt->_TcpEnabledEvents &= ~tcpClrEv; // clear some of them pDcpt->_EthEnabledEvents &= ~ethClrEvents; pDcpt->_TcpPendingEvents &= ~tcpClrEv; // remove them from un-ack list pDcpt->_EthPendingEvents &= ~ethClrEvents; EthEventsEnableClr(ethClrEvents); // no longer enabled EthEventsClr(ethClrEvents); // clear the pending ones if(pDcpt->_TcpEnabledEvents != 0) { SYS_INT_SourceRestore(pMacD->mData._macIntSrc, ethILev); // re-enable } return TCPIP_MAC_EVRES_OK; }
/******************************************************************************* Function: TCPIP_MAC_EVENT_RESULT PIC32MACEventSetNotifyHandler(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, pMacEventF eventHandler, void* hParam) Summary: Sets a new event notification handler. Description: This function sets a new event notification handler. This is a handler specified by the user of the stack. The caller can use the handler to be notified of MAC events. Whenever a notification occurs the passed events have to be eventually processed: - Stack should process the TCPIP_EV_RX_PKTPEND, TCPIP_EV_TX_DONE events - Process the specific (error) condition - Acknowledge the events by calling PIC32MACEventAck() so that they can be re-enabled. Precondition: TCPIPInit should have been called. tcpEvGroup valid value Parameters: hMac - parameter identifying the intended MAC tcpEvGroup - group of events the notification handler refers to eventHandler - the event notification handler Returns: TCPIP_MAC_EVRES_OK if operation succeeded, an error code otherwise Example: <code> PIC32MACEventSetNotifyHandler( hMac, TCPIP_MAC_EVGROUP_ALL, myEventHandler, myParam ); </code> Remarks: The notification handler will be called from the ISR which detects the corresponding event. The event notification handler has to be kept as short as possible and non-blocking. Mainly useful for RTOS integration where this handler will wake-up a thread that waits for a MAC event to occur. The event notification system also enables the user of the TCPIP stack to call into the stack for processing only when there are relevant events rather than being forced to periodically call from within a loop at unknown moments. Without a notification handler the stack user can still call PIC32MACEventGetPending() to see if processing by the stack needed. This is a default way of adding interrupt processing to the stack. A separate ISR to catch the Ethernet MAC events and process accordingly could be added. All the groups specified in the TCPIP_MAC_EVENT_GROUP enumeration is supported. However, once a handler for TCPIP_MAC_EVGROUP_ALL is registered all event processing will be reported using this global handler. Use 0 to remove the handler for a specific event group. Not multi-threaded safe accross different TCPIP_MAC_EVENT_GROUP groups. *****************************************************************************/ TCPIP_MAC_EVENT_RESULT PIC32MACEventSetNotifyHandler(TCPIP_MAC_HANDLE hMac, TCPIP_MAC_EVENT_GROUP tcpEvGroup, pMacEventF eventHandler, void* hParam) { int ethILev; PIC32_EMB_MAC_DCPT* pMacD = (PIC32_EMB_MAC_DCPT*)hMac; PIC32_EV_GROUP_DCPT* pDcpt = pMacD->mData._pic32_ev_group_dcpt+tcpEvGroup; if(pDcpt->_TcpEnabledEvents != 0) { // already have some active ethILev = SYS_INT_SourceDisable(pMacD->mData._macIntSrc); // stop ints for a while pDcpt->_TcpNotifyFnc = eventHandler; // set new handler pDcpt->_TcpNotifyParam = hParam; SYS_INT_SourceStatusClear(pMacD->mData._macIntSrc); SYS_INT_SourceRestore(pMacD->mData._macIntSrc, ethILev); // re-enable } else { pDcpt->_TcpNotifyFnc = eventHandler; // set new handler pDcpt->_TcpNotifyParam = hParam; } return TCPIP_MAC_EVRES_OK; }