📄 lightswitch.c
字号:
} while (psMcpsInd != NULL);
/* Check for anything on the MLME upward queue */
do
{
psMlmeInd = psAppQApiReadMlmeInd();
if (psMlmeInd != NULL)
{
vProcessIncomingMlme(psMlmeInd);
vAppQApiReturnMlmeIndBuffer(psMlmeInd);
}
} while (psMlmeInd != NULL);
/* Check for anything on the AHI upward queue */
do
{
psAHI_Ind = psAppQApiReadHwInd();
if (psAHI_Ind != NULL)
{
vProcessIncomingHwEvent(psAHI_Ind);
vAppQApiReturnHwIndBuffer(psAHI_Ind);
}
} while (psAHI_Ind != NULL);
}
/****************************************************************************
*
* NAME: vProcessIncomingMlme
*
* DESCRIPTION:
* Process any incoming managment events from the stack.
*
* PARAMETERS: Name RW Usage
* psMlmeInd
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PRIVATE void vProcessIncomingMlme(MAC_MlmeDcfmInd_s *psMlmeInd)
{
/* We respond to several MLME indications and confirmations, depending
on mode */
switch (psMlmeInd->u8Type)
{
/* Deferred confirmation that the scan is complete */
case MAC_MLME_DCFM_SCAN:
vPrintString("scan cmplt\r\n");
/* Only respond to this if scanning */
if (sDeviceData.sSystem.eState == E_STATE_SCANNING)
{
vHandleActiveScanResponse(psMlmeInd);
}
break;
/* Deferred confirmation that the association process is complete */
case MAC_MLME_DCFM_ASSOCIATE:
vPrintString("assc resp\r\n");
/* Only respond to this if associating */
if (sDeviceData.sSystem.eState == E_STATE_ASSOCIATING)
{
vHandleAssociateResponse(psMlmeInd);
}
break;
default:
break;
}
}
/****************************************************************************
*
* NAME: vProcessIncomingData
*
* DESCRIPTION:
* Process incoming data events from the stack.
*
* PARAMETERS: Name RW Usage
* psMcpsInd
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PRIVATE void vProcessIncomingData(MAC_McpsDcfmInd_s *psMcpsInd)
{
switch (psMcpsInd->u8Type)
{
/* Deferred confirmation that data frame has been transmitted, or not */
case MAC_MCPS_DCFM_DATA:
vPrintString("data in\r\n");
/* Only respond if the light bulb application is running */
if (sDeviceData.sSystem.eState == E_STATE_RUNNING)
{
/* Check that the frame transmission was successful */
if (psMcpsInd->uParam.sDcfmData.u8Status == MAC_ENUM_SUCCESS)
{
/* Frame transmission complete, go to sleep until next event */
vLightSwitchSleep();
}
}
break;
}
}
/****************************************************************************
*
* NAME: vProcessIncomingHwEvent
*
* DESCRIPTION:
* Process any hardware events.
*
* PARAMETERS: Name RW Usage
* psAHI_Ind
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PRIVATE void vProcessIncomingHwEvent(AppQApiHwInd_s *psAHI_Ind)
{
/* No hardware events generated to nothing to be done here */
}
/****************************************************************************
*
* NAME: vStartScan
*
* DESCRIPTION:
* Start a scan to search for a network to join.
*
* PARAMETERS: Name RW Usage
* None.
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PRIVATE void vStartScan(void)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
sDeviceData.sSystem.eState = E_STATE_SCANNING;
/* Request scan */
sMlmeReqRsp.u8Type = MAC_MLME_REQ_SCAN;
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqScan_s);
sMlmeReqRsp.uParam.sReqScan.u8ScanType = MAC_MLME_SCAN_TYPE_ACTIVE;
sMlmeReqRsp.uParam.sReqScan.u32ScanChannels = SCAN_CHANNELS;
sMlmeReqRsp.uParam.sReqScan.u8ScanDuration = 3;
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
/* Check immediate response */
if (sMlmeSyncCfm.u8Status != MAC_MLME_CFM_DEFERRED)
{
/* Unexpected result: scan request should result in a deferred
confirmation (i.e. we will receive it later) */
}
}
/****************************************************************************
*
* NAME: vHandleActiveScanResponse
*
* DESCRIPTION:
* Handle the reponse generated by the stack as a result of the network scan.
*
* PARAMETERS: Name RW Usage
* psMlmeInd
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PRIVATE void vHandleActiveScanResponse(MAC_MlmeDcfmInd_s *psMlmeInd)
{
MAC_PanDescr_s *psPanDesc;
int i;
/* Make sure it is what we're after */
if ((psMlmeInd->uParam.sDcfmScan.u8Status == MAC_ENUM_SUCCESS)
&& (psMlmeInd->uParam.sDcfmScan.u8ScanType == MAC_MLME_SCAN_TYPE_ACTIVE))
{
/* Determine which, if any, network contains demo coordinator.
Algorithm for determining which network to connect to is
beyond the scope of 802.15.4, and we use a simple approach
of matching the required PAN ID and short address, both of
which we already know */
i = 0;
while (i < psMlmeInd->uParam.sDcfmScan.u8ResultListSize)
{
psPanDesc = &psMlmeInd->uParam.sDcfmScan.uList.asPanDescr[i];
if ( (psPanDesc->sCoord.u16PanId == PAN_ID)
&& (psPanDesc->sCoord.u8AddrMode == 2)
&& (psPanDesc->sCoord.uAddr.u16Short == COORD_ADDR))
{
/* Matched so start to synchronise and associate */
sDeviceData.sSystem.u8Channel = psPanDesc->u8LogicalChan;
vStartAssociate();
return;
}
i++;
}
/* Failed to find coordinator: keep trying */
vStartScan();
}
}
/****************************************************************************
*
* NAME: vStartAssociate
*
* DESCRIPTION:
* Start the association process with the network coordinator.
*
* PARAMETERS: Name RW Usage
* None.
*
* RETURNS:
* None.
*
* NOTES:
* Assumes that a network has been found during the network scan.
****************************************************************************/
PRIVATE void vStartAssociate(void)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
sDeviceData.sSystem.eState = E_STATE_ASSOCIATING;
/* Create associate request. We know short address and PAN ID of
coordinator as this is preset and we have checked that received
beacon matched this */
sMlmeReqRsp.u8Type = MAC_MLME_REQ_ASSOCIATE;
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqAssociate_s);
sMlmeReqRsp.uParam.sReqAssociate.u8LogicalChan = sDeviceData.sSystem.u8Channel;
sMlmeReqRsp.uParam.sReqAssociate.u8Capability = 0x80; /* We want short address, other features off */
sMlmeReqRsp.uParam.sReqAssociate.u8SecurityEnable = FALSE;
sMlmeReqRsp.uParam.sReqAssociate.sCoord.u8AddrMode = 2;
sMlmeReqRsp.uParam.sReqAssociate.sCoord.u16PanId = PAN_ID;
sMlmeReqRsp.uParam.sReqAssociate.sCoord.uAddr.u16Short = COORD_ADDR;
/* Put in associate request and check immediate confirm. Should be
deferred, in which case response is handled by event handler */
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
if (sMlmeSyncCfm.u8Status != MAC_MLME_CFM_DEFERRED)
{
/* Unexpected result */
}
}
/****************************************************************************
*
* NAME: vHandleAssociateResponse
*
* DESCRIPTION:
* Handle the response generated by the stack as a result of the associate
* start request.
*
* PARAMETERS: Name RW Usage
* psMlmeInd
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PRIVATE void vHandleAssociateResponse(MAC_MlmeDcfmInd_s *psMlmeInd)
{
/* If successfully associated with network coordinator */
if (psMlmeInd->uParam.sDcfmAssociate.u8Status == MAC_ENUM_SUCCESS)
{
/* Store short address that we have been assigned */
sDeviceData.sSystem.u16ShortAddr = psMlmeInd->uParam.sDcfmAssociate.u16AssocShortAddr;
/* We are now in the running state */
sDeviceData.sSystem.eState = E_STATE_RUNNING;
/* Go to sleep until light switch is pressed */
vLightSwitchSleep();
}
else
{
/* Try, try again */
vStartAssociate();
}
}
/****************************************************************************
*
* NAME: vTxDataFrame
*
* DESCRIPTION:
* Transmit a single data frame to the network coordinator. The payload can
* be set to anything at all. The coordinator will toggle the state of the
* light bulb upon reception of a data frame from a light switch that is part
* of the network regardless of the contents of the payload.
*
* PARAMETERS: Name RW Usage
* None.
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PRIVATE void vTxDataFrame(void)
{
MAC_McpsReqRsp_s sMcpsReqRsp;
MAC_McpsSyncCfm_s sMcpsSyncCfm;
uint8 *pu8Payload;
/* Create frame transmission request */
sMcpsReqRsp.u8Type = MAC_MCPS_REQ_DATA;
sMcpsReqRsp.u8ParamLength = sizeof(MAC_McpsReqData_s);
/* Set handle so we can match confirmation to request */
sMcpsReqRsp.uParam.sReqData.u8Handle = 1;
/* Use short address for source */
sMcpsReqRsp.uParam.sReqData.sFrame.sSrcAddr.u8AddrMode = 2;
sMcpsReqRsp.uParam.sReqData.sFrame.sSrcAddr.u16PanId = PAN_ID;
sMcpsReqRsp.uParam.sReqData.sFrame.sSrcAddr.uAddr.u16Short = sDeviceData.sSystem.u16ShortAddr;
/* Use short address for destination */
sMcpsReqRsp.uParam.sReqData.sFrame.sDstAddr.u8AddrMode = 2;
sMcpsReqRsp.uParam.sReqData.sFrame.sDstAddr.u16PanId = PAN_ID;
sMcpsReqRsp.uParam.sReqData.sFrame.sDstAddr.uAddr.u16Short = COORD_ADDR;
/* Frame requires ack but not security, indirect transmit or GTS */
sMcpsReqRsp.uParam.sReqData.sFrame.u8TxOptions = MAC_TX_OPTION_ACK;
sMcpsReqRsp.uParam.sReqData.sFrame.u8SduLength = 8;
pu8Payload = sMcpsReqRsp.uParam.sReqData.sFrame.au8Sdu;
/* Set payload data to anything at all */
pu8Payload[0] = 0;
pu8Payload[1] = 1;
pu8Payload[2] = 2;
pu8Payload[3] = 3;
pu8Payload[4] = 4;
pu8Payload[5] = 5;
/* Request transmit */
vAppApiMcpsRequest(&sMcpsReqRsp, &sMcpsSyncCfm);
}
/****************************************************************************
*
* NAME: vInitUart
*
* DESCRIPTION:
* Initialise the UART
*
* RETURNS:
* None.
*
****************************************************************************/
PRIVATE void vInitUart(void)
{
/* Enable UART 0: 19200-8-N-1 */
vAHI_UartEnable(E_AHI_UART_0);
vAHI_UartReset(E_AHI_UART_0, TRUE, TRUE);
vAHI_UartReset(E_AHI_UART_0, FALSE, FALSE);
vAHI_UartSetClockDivisor(E_AHI_UART_0, E_AHI_UART_RATE_19200);
vAHI_UartSetControl(E_AHI_UART_0, FALSE, FALSE, E_AHI_UART_WORD_LEN_8, TRUE, FALSE);
vAHI_UartSetInterrupt(E_AHI_UART_0, FALSE, FALSE, FALSE, TRUE, E_AHI_UART_FIFO_LEVEL_1);
vPrintString("uart on\r\n");
}
/****************************************************************************
*
* NAME: vPrintString
*
* DESCRIPTION:
* Sends a string to the circular buffer ready for printing to the UART.
*
* PARAMETERS: Name RW Usage
* pcMessage R Null-terminated message to send
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vPrintString(char *pcMessage)
{
while (*pcMessage)
{
while ((u8AHI_UartReadLineStatus(0) & 0x20) == 0);
vAHI_UartWriteData(0, *pcMessage);
pcMessage++;
}
}
/****************************************************************************/
/*** END OF FILE ***/
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -