#include <BowlerCom.h> BowlerCom com(Serial); void setup() { com.begin(9600); } void loop() { com.server(); }
A library for controlling Bowler devices with C
#Theory Of Operation
The Bowler stack is based off of a pair of abstract data streams. These streams can be passed to the Bowler Server stack to be processed into packets.
The streams are contained in the "BYTE_FIFO_STORAGE" struct. The FIFO is initialized by the stack by passing it a buffer and the size.
static BYTE privateRXCom[comBuffSize]; static BYTE_FIFO_STORAGE store; InitByteFifo(&store,privateRXCom,comBuffSize);
Once the FIFO for receiving packets is established, bytes can be added from whatever physical layer is needed:
BYTE err; BYTE b= getLatestByte(); FifoAddByte(&store, b, &err);
The FiFO can be checked for a packet by calling a GetBowlerPacket(), then processed by the stack:
BowlerPacket Packet; if(GetBowlerPacket(&Packet,&store)){ //Now the Packet struct contains the parsed packet data Process_Self_Packet(&Packet); // The call backs for processing the packet have been called // and the Packet struct now contains the data // to be sent back to the client as a response. } int i=0; for(i=0;i< GetPacketLegnth(&Packet);i++){ //Grab the response packet one byte at a time and push it out the physical layer writeToPyhsicalLayerImp(Packet.stream[i]); }
To add new RPC's to the stack, we create a linked list element called a Namespace.
For a detailed example of different types of functionality take a look at the PID namespace:
To add a standard namespace, such as PID, to the stack, call addNamespaceToList:
addNamespaceToList((NAMESPACE_LIST * ) getBcsPidNamespace());
This new namespace and its call backs will be added to the Process_Self_Packet function call.
To make a custom namespace, first you define the NAMESPACE_LIST linked list struct element. This also requires a call back function for asynchronus packets.
BOOL pidAsyncEventCallbackLocal(BowlerPacket *Packet,BOOL (*pidAsyncCallbackPtr)(BowlerPacket *Packet)){ //Run any cooperative tasks //Pack and send any packets, more then one is ok } static NAMESPACE_LIST bcsPid ={"bcs.pid.*;1.0;;",// The string defining the namespace NULL,// the first element in the RPC list &pidAsyncEventCallbackLocal,// async for this namespace NULL// no initial elements to the other namesapce field. };
Next you define an RPC struct element. This element includes the callback for processing the specified RPC packet.
static RPC_LIST bcsPid__PID={BOWLER_GET, "_pid", &processPIDGet, ((const char [2]){BOWLER_I08,//channel 0}),// Response arguments BOWLER_POST,// response method ((const char [3]){BOWLER_I08,//channel BOWLER_I32,//current position 0}),// Response arguments NULL //Termination };
Finally you add the new RPC's to the namespace and the new namespace to the processing stack:
addRpcToNamespace(&bcsPid,& bcsPid__PID); addNamespaceToList(&bcsPid);
wget http://ww1.microchip.com/downloads/en/DeviceDoc/xc32-v1.00-linux.zip unzip xc32-v1.00-linux.zip sudo chmod +x xc32-v1.00-linux-installer.run sudo ./xc32-v1.00-linux-installer.run
sudo apt-get install -y --force-yes avr-libc gcc-avr git build-essential