📄 wirelessuart.c
字号:
/****************************************************************************
*
* MODULE: Wireless Uart code
*
* COMPONENT: $RCSfile: WirelessUart.c,v $
*
* VERSION: $Name: $
*
* REVISION: $Revision: 1.8 $
*
* DATED: $Date: 2006/05/17 08:47:07 $
*
* STATUS: $State: Exp $
*
* AUTHOR: GPfef
*
* DESCRIPTION:
*
*
* LAST MODIFIED BY: $Author: gpfef $
* $Modtime: $
*
****************************************************************************
*
* (c) Copyright 2006 JENNIC Ltd
*
****************************************************************************/
/****************************************************************************/
/*** Include files ***/
/****************************************************************************/
#include "jendefs.h"
#include <AppHardwareApi.h>
#include <string.h>
#include "Button.h"
#include "gdb.h"
#include "JZ_Api.h"
#include "af.h"
#include "aps.h"
#include "af_profile.h"
#include "apl_define.h"
#include "zdp.h"
#include "WirelessUartProfile.h"
#include "serialq.h"
#include "uart.h"
#include "serial.h"
/****************************************************************************/
/*** Macro Definitions ***/
/****************************************************************************/
/* number of spaces in hardware event queue */
#define HW_INT_Q_SIZE 32
#define HW_INT_Q_PTR_MASK 0x1f
/* DIO lines used to drive LEDs */
#define LED_OUTPUTS_MASK 0x0000C000UL
#define LED1_MASK 0x00004000UL
#define LED2_MASK 0x00008000UL
/* Wireless UART device data */
#define MAX_DATA_PER_FRAME 64
/* number of 10ms intervals which may elapse while waiting for match
descriptor response, before making another request */
#define MAX_BIND_RESPONSE_WAIT 500
/* max number of 10ms intervals waiting for response before re-sending
packet */
#define MAX_KVP_RESPONSE_WAIT 4
/****************************************************************************/
/*** Type Definitions ***/
/****************************************************************************/
/* Button values */
typedef enum
{
E_KEY_0 = BUTTON_0_MASK,
E_KEY_1 = BUTTON_1_MASK,
} teKeyValues;
/* binding state machine */
typedef enum
{
E_BIND_NONE,
E_BIND_BINDING,
E_BIND_MATCHED
} teBindType;
/* structure used to pass hardware events to application */
typedef struct
{
uint32 u32Device;
uint32 u32ItemBitmap;
} tsHwIntData;
/* All application data with scope within the entire file is kept here, */
typedef struct
{
struct
{
uint32 u32AppApiVersion;
uint32 u32HwApiVersion;
uint32 u32CalibratedTimeout;
uint16 u16MatchAddr;
uint8 u8MatchEndpoint;
uint8 u8WuartEndpoint;
teBindType eBound;
uint16 u16BindResponseTimeout;
bool_t bAwaitingResponse;
uint8 u8KvpResponseTimeout;
uint8 u8TxFrameHandle;
uint8 u8RxFrameHandle;
} sSystem;
/* Queue for hardware interrupts */
struct
{
tsHwIntData asHwIntData[HW_INT_Q_SIZE];
volatile uint8 u8ReadPtr;
volatile uint8 u8WritePtr;
} sQueue;
} tsWuart;
/****************************************************************************/
/*** Local Function Prototypes ***/
/****************************************************************************/
PRIVATE void vInitDevice(void);
PRIVATE void vInit(void);
PRIVATE void vTxData(void);
PRIVATE void vPerformMatchRequest(void);
PRIVATE void vCheckForBindResponseTimeout(void);
PRIVATE void vCheckForKvpResponseTimeout(void);
/****************************************************************************/
/*** Exported Variables ***/
/****************************************************************************/
/****************************************************************************/
/*** Local Variables ***/
/****************************************************************************/
/* File scope data */
PRIVATE tsWuart sWuart;
/****************************************************************************/
/*** Exported Functions ***/
/****************************************************************************/
/****************************************************************************
*
* NAME: AppColdStart
*
* DESCRIPTION:
* Entry point for application from boot loader. Initialises system.
*
* RETURNS:
* Never returns.
*
****************************************************************************/
PUBLIC void AppColdStart(void)
{
/* Debug hooks: include these regardless of whether debugging or not */
HAL_GDB_INIT();
HAL_BREAKPOINT();
/* General initialisation: reset hardware, set some values in PIB */
JZS_sConfig.u32Channel = 0x11;
JZS_sConfig.u16PanId = 0x1aab;
/* General initialisation */
vInit();
/* No return from the above function call */
}
/****************************************************************************
*
* NAME: AppWarmStart
*
* DESCRIPTION:
* Entry point for application from boot loader. Simply jumps to AppColdStart
* as, in this instance, application will never warm start.
*
* RETURNS:
* Never returns.
*
****************************************************************************/
PUBLIC void AppWarmStart(void)
{
AppColdStart();
}
/****************************************************************************
*
* NAME: JZA_boAppStart
*
* DESCRIPTION:
* Adds a simple descriptor for the UART input and output clusters.
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC BOOL JZA_boAppStart(void)
{
/* Controller has 1 endpoints, with 1 input and 1 output clusters */
uint8 u8DeviceVer = 0x00;
uint8 u8Flags = 0x00;
uint8 u8EndPoint = sWuart.sSystem.u8WuartEndpoint;
uint16 u16DeviceId = 0x0000;
/* use the same cluster ID for the input and output clusters. This means
that the output cluster from one node will match the input cluster of the
other node */
uint8 u8InputClusterCnt = 1;
uint8 au8InputClusterList[] = {WUP_CID_UART};
uint8 u8OutputClusterCnt = 1;
uint8 au8OutputClusterList[] = {WUP_CID_UART};
(void)afmeAddSimpleDesc(u8EndPoint, WUP_PROFILE_ID, u16DeviceId,
u8DeviceVer, u8Flags, u8InputClusterCnt,
au8InputClusterList, u8OutputClusterCnt,
au8OutputClusterList);
/* start as a coordinator/router/end device according to the make file*/
JZS_vStartStack();
return TRUE;
}
/****************************************************************************
*
* NAME: JZA_vAppEventHandler
*
* DESCRIPTION:
* Main user routine. This is called by the Basic Operating System (BOS)
* for the first time after the device has successfully started/joined a
* network and then regularly thereafter.
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vAppEventHandler(void)
{
tsHwIntData *psHwIntData;
char cCharIn;
bool_t bBufferFull;
/* indicate that the device has started/joined a network and that the application
is now running */
vAHI_DioSetOutput(LED1_MASK, 0);
/* ensure that LED 2 is on while waiting to bind */
if (sWuart.sSystem.eBound != E_BIND_MATCHED)
{
vAHI_DioSetOutput(0, LED2_MASK);
}
/* Check queue for hardware interrupts, and process. Only process one per call */
while (sWuart.sQueue.u8WritePtr != sWuart.sQueue.u8ReadPtr)
{
psHwIntData = &sWuart.sQueue.asHwIntData[sWuart.sQueue.u8ReadPtr];
switch (psHwIntData->u32Device)
{
case E_AHI_DEVICE_UART0:
/* If data has been received */
if ((psHwIntData->u32ItemBitmap & 0x000000FF) == E_AHI_UART_INT_RXDATA)
{
/* Process UART0 RX interrupt */
cCharIn = ((psHwIntData->u32ItemBitmap & 0x0000FF00) >> 8);
/* add character to UART Rx buffer; turn LED2 on if buffer full */
bBufferFull = bUART_RxCharISR((psHwIntData->u32ItemBitmap & 0x0000FF00) >> 8);
if (bBufferFull)
{
vAHI_DioSetOutput(0, LED2_MASK);
}
}
else if (psHwIntData->u32ItemBitmap == E_AHI_UART_INT_TX)
{
/* Process UART0 TX interrupt */
vUART_TxCharISR();
}
break;
/* If this is an event from timer 1 (which occurs every 10ms) */
case E_AHI_DEVICE_TIMER1:
/* check binding state */
if (sWuart.sSystem.eBound == E_BIND_MATCHED)
{
/* already bound so we can send data received over the UART
to the matched node */
if (sWuart.sSystem.bAwaitingResponse)
{
/* still waiting for a kvp response from the last packet
so increment the timeout counter */
vCheckForKvpResponseTimeout();
}
else
{
/* not waiting for a response so can send a new packet */
vTxData();
}
}
else if (sWuart.sSystem.eBound == E_BIND_NONE)
{
/* there has not yet been an attempt to find a matching node,
so try to find one now */
vPerformMatchRequest();
}
else if (sWuart.sSystem.eBound == E_BIND_BINDING)
{
/* already tried to find a matching node; check how long ago
this occurred and re-start the process if necessary */
vCheckForBindResponseTimeout();
}
break;
default:
break;
}
/* advance hardware queue pointer */
sWuart.sQueue.u8ReadPtr = (sWuart.sQueue.u8ReadPtr + 1) & HW_INT_Q_PTR_MASK;
}
/* check if user is trying to clear the buffer overflow LED */
if ((u8ButtonReadRfd() == E_KEY_1) && (sWuart.sSystem.eBound == E_BIND_MATCHED))
{
vAHI_DioSetOutput(LED2_MASK, 0);
}
}
/****************************************************************************
*
* NAME: JZA_vPeripheralEvent
*
* DESCRIPTION:
* Adds events to the hardware event queue.
*
* PARAMETERS: Name RW Usage
* u32Device R Peripheral responsible for interrupt e.g DIO
* u32ItemBitmap R Source of interrupt e.g. DIO bit map
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vPeripheralEvent(uint32 u32Device, uint32 u32ItemBitmap)
{
tsHwIntData *psHwIntData;
uint8 u8WriteNextPtr;
/* Queue event for processing during appKeyOperationKey call */
u8WriteNextPtr = (sWuart.sQueue.u8WritePtr + 1) & HW_INT_Q_PTR_MASK;
if (u8WriteNextPtr != sWuart.sQueue.u8ReadPtr)
{
/* There is space on queue */
psHwIntData = &sWuart.sQueue.asHwIntData[sWuart.sQueue.u8WritePtr];
psHwIntData->u32Device = u32Device;
psHwIntData->u32ItemBitmap = u32ItemBitmap;
sWuart.sQueue.u8WritePtr = u8WriteNextPtr;
}
/* If no space on queue, interrupt is silently discarded */
}
/****************************************************************************
*
* NAME: JZA_vAppDefineTasks
*
* DESCRIPTION:
* Can be used to add additional tasks.
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vAppDefineTasks(void)
{
}
/****************************************************************************
*
* NAME: JZA_eAfKvpObject
*
* DESCRIPTION:
* Receives incoming KVP data frames
*
* PARAMETERS: Name RW Usage
* afSrcAddr R Source address of KVP frame
* u8DstEndpoint R Destination endpoint for frame
* *pu8ClusterId R Pointer to Cluster ID for KVP frame
* eCommandTypeId R Command type specified by the frame
* u16AttributeId R Target Attribute ID of Cluster
* *pu8AfduLength R Pointer to length of data portion of frame
* *pu8Afdu R Pointer to data portion of frame
*
* RETURNS:
* Application framework error code
*
****************************************************************************/
PUBLIC AF_ERROR_CODE JZA_eAfKvpObject (AF_ADDRTYPE afSrcAddr,
uint8 u8DstEndpoint,
uint8 u8SequenceNum,
uint8 *pu8ClusterId,
AF_COMMAND_TYPE_ID eCommandTypeId,
uint16 u16AttributeId,
uint8 *pu8AfduLength,
uint8 *pu8Afdu)
{
int i;
uint16 u16DeviceAddr;
/* check command frame is valid and for correct endpoint*/
if ( (afSrcAddr.hAddrMode != DEV_16BIT_ADDR)
|| (u8DstEndpoint != sWuart.sSystem.u8WuartEndpoint))
{
return KVP_INVALID_ENDPOINT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -