#include "proto.h" /* Define the types of the array entries of stage one and two */ typedef struct { protoTime timestamp; unsigned char dataByte; } stageOneEntry; typedef struct { protoTime timestamp; unsigned int dataDWord; } stageTwoEntry; /* All functions except for PROTO_Init are declared static, because they don't have to be visible externally */ /* Stage one: Process raw trace data, generate bytes out of raw trace data */ static protoSizeT PROTOAPI processStageOne( protoContext context, protoPtr arrayOut, protoSizeT arrayOutSize, protoPtr arrayIn, protoSizeT arrayInSize, protoPtr localdata) { protoSizeT i, j; int h; stageOneEntry *stageOneArray; /* Pointer to array which will contain the output records */ protoTime traceTime; /* timestamp of raw trace data record */ int traceChannel[2]; /* Bit value of the two signals which are processed */ int prevClk; unsigned char data; /* traceChannel[] contains the two bit values (0,1) of the two used signal channels. The following macros simplify the access. */ #define SER_CLK traceChannel[0] #define SER_DATA traceChannel[1] stageOneArray=(stageOneEntry *)arrayOut; /* type cast to the used output record type */ /* Find first trace entry with SER_CLK==0 */ j=0; /* index of raw trace record */ while (j=arrayInSize) /* The SER_CLK never was 0, so we can't generate output data */ return 0; /* Read in bits at rising edges of SER_CLK */ i=0; /* number of output array entries */ h=0; /* number of read bits */ j++; prevClk=0; data=0; while (j=arrayOutSize) /* If there is no free space to store more */ return PROTO_PROCESS_OUTOFMEMORY; /* records, the processing is aborted */ stageOneArray[i].timestamp=traceTime; /* Store time of first processed bit */ } data>>=1; /* shift in lowest bits first */ if (SER_DATA) data|=0x80; h++; /* Count number of bits */ } prevClk=SER_CLK; /* If we shifted in 8 bits, store a byte into output array */ if (h==8) { stageOneArray[i].dataByte=data; i++; data=0; h=0; } } return i; } /* Display Stage One data */ static void PROTOAPI displayStageOne( protoContext context, protoPtr pdata, protoPtr localdata) { stageOneEntry *entry; entry=(stageOneEntry *)pdata; /* Cast to correct type */ PROTO_Control(context, PROTO_CONTROL_INDENT); PROTO_Control(context, PROTO_ATTRIBUTE_LIGHT); PROTO_Puts(context, "BYTE : "); PROTO_Control(context, PROTO_ATTRIBUTE_NORM); PROTO_Printf(context, "0x%02x ", entry->dataByte); } /* Stage Two: Process data from Stage One (bytes) and generate Stage Two data (Dwords) */ static protoSizeT PROTOAPI processStageTwo( protoContext context, protoPtr arrayOut, protoSizeT arrayOutSize, protoPtr arrayIn, protoSizeT arrayInSize, protoPtr localdata) { stageOneEntry *stageOneArray; stageTwoEntry *stageTwoArray; protoSizeT i,j; unsigned int dataDWord; int shift; stageOneArray=(stageOneEntry *)arrayIn; /* Data from Stage One */ stageTwoArray=(stageTwoEntry *)arrayOut; /* Stage Two data which will be generated in this function */ /* Read in bytes in little endian order, LSB first */ j=0; dataDWord=0; shift=0; for (i=0;i=arrayOutSize) /* If there is no space for the */ return PROTO_PROCESS_OUTOFMEMORY; /* output record, abort the processing */ stageTwoArray[j].timestamp=stageOneArray[i].timestamp; } dataDWord |= ((unsigned int)stageOneArray[i].dataByte)<dataDWord); } int PROTOAPI PROTO_Init(protoContext context, int command) { /* Besides analyzer.proto.list there are other commands, which can be implemented in the used defined DLL. (For example analyzer.proto.find). This option will be described in a future application note. For this example only analyzer.proto.list is implemented. */ if (command == PROTO_COMMAND_LIST) { /* Define the two required signal channels */ PROTO_Parse(context, (protoPtr) 0, "", PROTO_PARSE_CHANNEL); PROTO_Parse(context, (protoPtr) 0, "", PROTO_PARSE_CHANNEL); /* Register callback functions for the three implemented stages */ PROTO_RegisterProcessCallback(context, processStageOne, (protoPtr) 0, sizeof(stageOneEntry), 1); PROTO_RegisterDisplayCallback(context, displayStageOne, (protoPtr) 0, 1); PROTO_RegisterProcessCallback(context, processStageTwo, (protoPtr) 0, sizeof(stageTwoEntry), 2); PROTO_RegisterDisplayCallback(context, displayStageTwo, (protoPtr) 0, 2); /* Default is to display only Stage Three data */ PROTO_SetDefaultLevel(context, 2); return PROTO_OK; } /* Other commands aren't implemented.*/ return 0; }